Redo reserializing components since the problem doesn't lie there
[Mograsim.git] / net.mograsim.logic.model.am2900 / src / net / mograsim / logic / model / examples / ReserializeJSONsSettingUsages.java
1 package net.mograsim.logic.model.examples;
2
3 import java.io.IOException;
4 import java.nio.file.Files;
5 import java.nio.file.Path;
6 import java.nio.file.Paths;
7 import java.util.Comparator;
8 import java.util.HashMap;
9 import java.util.Map;
10 import java.util.Map.Entry;
11 import java.util.Optional;
12 import java.util.Scanner;
13 import java.util.Set;
14 import java.util.function.Function;
15 import java.util.stream.Collectors;
16 import java.util.stream.Stream;
17
18 import net.mograsim.logic.model.am2900.Am2900Loader;
19 import net.mograsim.logic.model.model.LogicModelModifiable;
20 import net.mograsim.logic.model.model.components.ModelComponent;
21 import net.mograsim.logic.model.model.components.submodels.SubmodelComponent;
22 import net.mograsim.logic.model.model.components.submodels.SubmodelInterface;
23 import net.mograsim.logic.model.model.wires.ModelWire;
24 import net.mograsim.logic.model.model.wires.MovablePin;
25 import net.mograsim.logic.model.model.wires.Pin;
26 import net.mograsim.logic.model.model.wires.PinUsage;
27 import net.mograsim.logic.model.serializing.DeserializedSubmodelComponent;
28 import net.mograsim.logic.model.serializing.IdentifyParams;
29 import net.mograsim.logic.model.serializing.IndirectModelComponentCreator;
30 import net.mograsim.logic.model.serializing.SubmodelComponentSerializer;
31 import net.mograsim.logic.model.snippets.highlevelstatehandlers.DefaultHighLevelStateHandler;
32
33 public class ReserializeJSONsSettingUsages
34 {
35         public static boolean changePinUsages = false;
36         public static boolean changeComponentNames = true;
37
38         public static void main(String[] args) throws IOException
39         {
40                 Am2900Loader.setup();
41                 try (Scanner sysin = new Scanner(System.in))
42                 {
43                         System.out.print("Directory to search for JSONs in / JSON file to reserialize >");
44                         Path root = Paths.get(sysin.nextLine());
45                         if (!Files.exists(root))
46                                 throw new IllegalArgumentException("Path doesn't exist");
47                         if (Files.isRegularFile(root))
48                                 reserializeJSON(root, sysin);
49                         else
50                         {
51                                 System.out.print("Recursive? >");
52                                 boolean recursive = Boolean.valueOf(sysin.nextLine());
53                                 try (Stream<Path> jsons = recursive ? Files.walk(root) : Files.list(root))
54                                 {
55                                         jsons.filter(Files::isRegularFile).filter(p -> p.getFileName().toString().endsWith(".json"))
56                                                         .forEach(j -> reserializeJSON(j, sysin));
57                                 }
58                         }
59                 }
60         }
61
62         public static void reserializeJSON(Path componentPath, Scanner sysin)
63         {
64                 try
65                 {
66                         DeserializedSubmodelComponent comp = (DeserializedSubmodelComponent) IndirectModelComponentCreator
67                                         .createComponent(new LogicModelModifiable(), "jsonfile:" + componentPath.toString());
68                         System.out.println("Reserializing " + componentPath);
69                         if (changePinUsages)
70                                 comp.getSupermodelPins().entrySet().stream().sorted(Comparator.comparing(Entry::getKey)).map(Entry::getValue).forEach(pin ->
71                                 {
72                                         PinUsage usage = null;
73                                         while (usage == null)
74                                                 try
75                                                 {
76                                                         System.out.print("  Usage for interface pin " + pin.name + " (empty: " + pin.usage + ") >");
77                                                         String usageStr = sysin.nextLine().toUpperCase();
78                                                         usage = usageStr.equals("") ? pin.usage
79                                                                         : usageStr.equals("I") ? PinUsage.INPUT
80                                                                                         : usageStr.equals("O") ? PinUsage.OUTPUT
81                                                                                                         : usageStr.equals("T") ? PinUsage.TRISTATE : PinUsage.valueOf(usageStr);
82                                                 }
83                                                 catch (@SuppressWarnings("unused") IllegalArgumentException e)
84                                                 {
85                                                         System.err.println("  Illegal usage");
86                                                 }
87                                         setInterfacePinUsage(comp, pin, usage);
88                                 });
89                         LogicModelModifiable submodelModifiable = comp.getSubmodelModifiable();
90                         Map<String, String> componentNameRemapping = new HashMap<>();
91                         if (changeComponentNames)
92                         {
93                                 componentNameRemapping.put(SubmodelComponent.SUBMODEL_INTERFACE_NAME, SubmodelComponent.SUBMODEL_INTERFACE_NAME);
94                                 LogicModelModifiable tempModel = new LogicModelModifiable();
95                                 IdentifyParams iP = new IdentifyParams();
96                                 submodelModifiable.getComponentsByName().entrySet().stream()
97                                                 .filter(e -> !e.getKey().equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
98                                                 .sorted(Comparator.comparing(Entry::getKey, ReserializeJSONsSettingUsages::compareStringsWithIntegers)).forEach(e ->
99                                                 {
100                                                         String oldName = e.getKey();
101                                                         ModelComponent subcomp = e.getValue();
102                                                         String defaultName = tempModel.getDefaultComponentName(subcomp);
103                                                         String newName = null;
104                                                         while (newName == null)
105                                                         {
106                                                                 System.out.print("  New name for component " + oldName + " of type " + subcomp.getIDForSerializing(iP)
107                                                                                 + " (empty: " + defaultName + ") >");
108 //                                                              newName = sysin.nextLine();
109                                                                 newName = "";
110                                                                 System.out.println();
111                                                                 if (newName.equals(""))
112                                                                         newName = defaultName;
113                                                                 if (tempModel.getComponentsByName().containsKey(newName))
114                                                                 {
115                                                                         System.err.println("  There already is a component with that name");
116                                                                         newName = null;
117                                                                 }
118                                                         }
119                                                         componentNameRemapping.put(oldName, newName);
120                                                         IndirectModelComponentCreator.createComponent(tempModel, subcomp.getIDForSerializing(iP),
121                                                                         subcomp.getParamsForSerializingJSON(iP), newName).moveTo(subcomp.getPosX(), subcomp.getPosY());
122                                                 });
123                                 SubmodelInterface tempSubmodelInterface = new SubmodelInterface(tempModel);
124                                 for (Pin p : submodelModifiable.getComponentsByName().get(SubmodelComponent.SUBMODEL_INTERFACE_NAME).getPins().values())
125                                         tempSubmodelInterface
126                                                         .addPin(new Pin(tempModel, tempSubmodelInterface, p.name, p.logicWidth, p.usage, p.getRelX(), p.getRelY()));
127                                 for (ModelWire w : submodelModifiable.getWiresByName().values())
128                                         createWire(componentNameRemapping::get, tempModel, w);
129
130                                 Optional<ModelComponent> o;
131                                 while ((o = submodelModifiable.getComponentsByName().values().stream()
132                                                 .filter(c -> !c.name.equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME)).findAny()).isPresent())
133                                         submodelModifiable.destroyComponent(o.get());
134
135                                 tempModel.getComponentsByName().values().stream().filter(c -> !c.name.equals(SubmodelComponent.SUBMODEL_INTERFACE_NAME))
136                                                 .forEach(c -> IndirectModelComponentCreator
137                                                                 .createComponent(submodelModifiable, c.getIDForSerializing(iP), c.getParamsForSerializingJSON(iP), c.name)
138                                                                 .moveTo(c.getPosX(), c.getPosY()));
139                                 for (ModelWire w : tempModel.getWiresByName().values())
140                                         createWire(Function.identity(), submodelModifiable, w);
141                         }
142                         SubmodelComponentSerializer.serialize(comp, componentPath.toString());
143                         if (changeComponentNames && (comp.getHighLevelStateHandler() == null
144                                         || !(comp.getHighLevelStateHandler() instanceof DefaultHighLevelStateHandler)))
145                         {
146                                 System.out.println("A non-default HighLevelStateHandler was detected. Check for changes there manually.");
147                                 System.out.print("Empty line to continue to next component, old component name to get new component name >");
148                                 for (String line = sysin.nextLine(); !line.equals(""); line = sysin.nextLine())
149                                         System.out.println(line + "->" + componentNameRemapping.get(line) + " >");
150                         }
151                 }
152                 catch (Exception e)
153                 {
154                         System.err.println("An error occurred visiting " + componentPath + ":");
155                         e.printStackTrace();
156                 }
157         }
158
159         private static ModelWire createWire(Function<String, String> componentNameRemapping, LogicModelModifiable tempModelForDefaultNames,
160                         ModelWire w)
161         {
162                 return new ModelWire(tempModelForDefaultNames, w.name,
163                                 getRemappedPin(componentNameRemapping, tempModelForDefaultNames, w.getPin1()),
164                                 getRemappedPin(componentNameRemapping, tempModelForDefaultNames, w.getPin2()), w.getPath());
165         }
166
167         private static Pin getRemappedPin(Function<String, String> componentNameRemapping, LogicModelModifiable tempModelForDefaultNames,
168                         Pin pin)
169         {
170                 return tempModelForDefaultNames.getComponentsByName().get(componentNameRemapping.apply(pin.component.name)).getPin(pin.name);
171         }
172
173         private static int compareStringsWithIntegers(String a, String b)
174         {
175                 int aLoc = 0;
176                 int bLoc = 0;
177                 for (;;)
178                 {
179                         if (aLoc == a.length())
180                         {
181                                 if (bLoc == b.length())
182                                         return 0;
183                                 return -1;
184                         }
185                         if (bLoc == b.length())
186                                 return 1;
187                         int aInt = 0;
188                         int aIntLen = 0;
189                         char nextCharA;
190                         for (;;)
191                         {
192                                 nextCharA = a.charAt(aLoc++);
193                                 if (nextCharA < '0' || nextCharA > '9')
194                                         break;
195                                 aIntLen++;
196                                 aInt = aInt * 10 + nextCharA - '0';
197                                 if (aLoc == a.length())
198                                         break;
199                         }
200                         int bInt = 0;
201                         int bIntLen = 0;
202                         char nextCharB;
203                         for (;;)
204                         {
205                                 nextCharB = b.charAt(bLoc++);
206                                 if (nextCharB < '0' || nextCharB > '9')
207                                         break;
208                                 bIntLen++;
209                                 bInt = bInt * 10 + nextCharB - '0';
210                                 if (bLoc == b.length())
211                                         break;
212                         }
213                         if (aIntLen != 0)
214                         {
215                                 if (bIntLen == 0)
216                                         return -1;
217                                 int comp = Integer.compare(aInt, bInt);
218                                 if (comp != 0)
219                                         return comp;
220                         } else
221                         {
222                                 if (bIntLen != 0)
223                                         return 1;
224                                 int comp = Character.compare(nextCharA, nextCharB);
225                                 if (comp != 0)
226                                         return comp;
227                         }
228                 }
229         }
230
231         private static void setInterfacePinUsage(DeserializedSubmodelComponent comp, Pin interfacePin, PinUsage usage)
232         {
233                 Set<ModelWire> wiresConnectedToPin = comp.submodel.getWiresByName().values().stream()
234                                 .filter(w -> w.getPin1() == interfacePin || w.getPin2() == interfacePin).collect(Collectors.toSet());
235                 LogicModelModifiable submodelModifiable = comp.getSubmodelModifiable();
236                 wiresConnectedToPin.forEach(submodelModifiable::destroyWire);
237                 comp.removeSubmodelInterface(interfacePin.name);
238                 comp.addSubmodelInterface(new MovablePin(submodelModifiable, comp, interfacePin.name, interfacePin.logicWidth, usage,
239                                 interfacePin.getRelX(), interfacePin.getRelY()));
240                 wiresConnectedToPin.forEach(w -> new ModelWire(submodelModifiable, w.getPin1(), w.getPin2()));
241         }
242 }