package net.automatalib.serialization.fsm;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import net.automatalib.automata.transout.impl.compact.CompactMealy;
import net.automatalib.words.Alphabet;
import net.automatalib.words.impl.Alphabets;

public class FSM {

    public static CompactMealy<String, String> parseMealy(File f) throws FileNotFoundException {

        final Scanner s = new Scanner(new FileReader(f));

        /* Keep track of which part in the FSM we are:
         *  0: State definition
         *  1: State vectors
         *  2: Transitions between states
         * We are only interested in part 3. */
        int currentPart = 0;

        Set<String> inputs = new HashSet<>();
        Set<Transition> transitions = new HashSet<>();
        List<String> states = new ArrayList<>();
        while (s.hasNextLine()) {
            final String line = s.nextLine();

            if (line.equals("---")) currentPart++;
            else if (currentPart == 2) {
                final String[] split = line.split(" ");

                	/*
                	 * If the split has length three, we assume one label per edge and merge two edges/lines.
                	 * Otherwise we obtain the transition from one edge/label.
                	 */
                	if(split.length == 3){
                		String line2 = s.nextLine();
                		String[] split2 = line2.split(" ");
                		final Transition t = new Transition(split[0], split2[1], split[2], split2[2]);
                        inputs.add(t.getInput());
                        if (!states.contains(t.getSource())) states.add(t.getSource());
		        if (!states.contains(t.getTarget())) states.add(t.getTarget());
		        transitions.add(t);
                	} else {
                		final Transition t = new Transition(split[0], split[1], split[2], split[3]);
                        inputs.add(t.getInput());
                        if (!states.contains(t.getSource())) states.add(t.getSource());
                        if (!states.contains(t.getTarget())) states.add(t.getTarget());
                        transitions.add(t);
                	}

            }
        }


        final Alphabet<String> a = Alphabets.fromCollection(inputs);

        CompactMealy<String, String> cm = new CompactMealy(a, states.size());

        Map<String, Integer> stateMap = new HashMap<>();
        for (String state : states) stateMap.put(state, cm.addState());

        cm.setInitial(stateMap.get("1"), true);

        for (Transition t : transitions) {
            cm.addTransition(stateMap.get(t.getSource()), t.getInput(), stateMap.get(t.getTarget()), t.getOutput());
        }

        s.close();

        return cm;
    }

    @EqualsAndHashCode
    public static class Transition {

        @Getter private final String source;
        @Getter private final String target;
        @Getter private final String input;
        @Getter private final String output;

        public Transition(final String source, final String target,
            final String input, final String output) {
            this.source = source;
            this.target = target;
            this.input = input.substring(1, input.length() - 1);
            this.output = output.substring(1, output.length() - 1);
        }
    }
}

@@ -1313,17 +1313,16 @@
         
-%09
 /*%0A     
@@ -1332,17 +1332,16 @@
         
-%09
  * If th
@@ -1438,17 +1438,16 @@
         
-%09
  * Other
@@ -1513,17 +1513,16 @@
         
-%09
  */%0A    
@@ -1537,11 +1537,11 @@
     
-%09
 if
+ 
 (spl
@@ -1555,16 +1555,17 @@
 th == 3)
+ 
 %7B%0A      
@@ -1570,26 +1570,28 @@
             
-%09%09
+    
 String line2
@@ -1623,18 +1623,20 @@
         
-%09%09
+    
 String%5B%5D
@@ -1671,34 +1671,36 @@
                 
+   
-%09%09
+ 
 final Transition
@@ -1774,36 +1774,32 @@
                 
-    
 inputs.add(t.get
@@ -1800,36 +1800,32 @@
 (t.getInput());%0A
-    
                 
@@ -1892,26 +1892,32 @@
 rce());%0A
-%09%09
+        
         
 if (!sta
@@ -1900,32 +1900,36 @@
                 
+    
 if (!states.cont
@@ -1980,18 +1980,21 @@
 ));%0A
-%09%09
+     
         
 tran
@@ -1981,32 +1981,39 @@
 );%0A             
+       
 transitions.add(
@@ -2032,17 +2032,16 @@
         
-%09
 %7D else %7B
@@ -2061,10 +2061,12 @@
     
+   
-%09%09
+ 
 fina
@@ -2150,36 +2150,32 @@
                 
-    
 inputs.add(t.get
@@ -2176,36 +2176,32 @@
 (t.getInput());%0A
-    
                 
@@ -2280,36 +2280,32 @@
                 
-    
 if (!states.cont
@@ -2364,36 +2364,32 @@
                 
-    
 transitions.add(
@@ -2412,12 +2412,10 @@
     
-%09
 %7D%0A
-%0A
     
@@ -2416,32 +2416,32 @@
 %7D%0A            %7D%0A
+
         %7D%0A%0A%0A    
@@ -2435,17 +2435,16 @@
      %7D%0A%0A
-%0A
         

Fix formatting issues