package ast;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import ast.Ast.Atom;
import ast.Ast.C;
import ast.Ast.Doc;
import ast.Ast.Mdf;
import ast.Ast.NormType;
import ast.Ast.Path;
import platformSpecific.javaTranslation.Resources;
import tools.Assertions;
import tools.Map;
import lombok.Value;
import lombok.EqualsAndHashCode;
public class PathAux {
public static Path Void() {return PathPrimitive._Void;}
public static Path Any() {return PathPrimitive._Any;}
public static Path Library() {return PathPrimitive._Library;}
public static boolean isValidOuter(String name) {
// thus invalid as pathName
if (name.equals("This")) { return true;}
if (name.equals("This0")) { return true;}
if (!name.startsWith("This")) { return false;}
int firstN = "This".length();
char c = name.charAt(firstN);
// first is 1--9 and all rest is 0-9
if ("123456789".indexOf(c) == -1) {return false;}
for (int i = firstN + 1; i < name.length(); i++) {
if ("0123456789".indexOf(name.charAt(i)) == -1) {
return false;
}
}
return true;
}
public static List<C> sToC(List<String> names){
return immCs(Map.of(s->C.of(s),names));
}
public static List<C> immCs(List<C> cs){
assert (cs=Collections.unmodifiableList(cs))!=null;
return cs;
}
public static List<C> parseValidCs(String cs) {
if (cs.equals("This0") || cs.equals("This")) {
return Collections.emptyList();
}
List<String> rowData = Arrays.asList(cs.split("\\."));
return PathAux.sToC(rowData);
}
public static boolean isValidPrimitiveName(String name){
Path p=PathPrimitive._parsePrimitive(name);
return p!=null;
}
public static boolean isValidClassName(String name) {
if(name.isEmpty()){ return false;}
if(isValidOuter(name)) { return false;}
if(isValidPrimitiveName(name)){return false;}
if (!isValidPathStart(name.charAt(0))) { return false;}
for (int i = 1; i < name.length(); i++) {
if (!isValidPathChar(name.charAt(i))) { return false; }
}
return true;
}
public static boolean isValidPathStart(char c) {
if (c == '%') { return true;}
if (c == '$') { return true;}
return Character.isUpperCase(c);
}
public static boolean isValidPathChar(char c) {
if (c == '%') { return true;}
if (c == '$') { return true;}
if (c == '_') { return true;}
assert c!='\t': c;
return Character.isUpperCase(c)
|| Character.isLowerCase(c)
|| Character.isDigit(c);
}
}
@Value @EqualsAndHashCode(callSuper=false)
class PathCore extends Path{
public String toString() { return sugarVisitors.ToFormattedText.of(this);}//otherwise lombock overrides it
public PathCore(int outerN, List<C> cBar) {
assert outerN>=0;
this.outerN = outerN;
this.cBar = cBar;
}
public static Path instance(int n,List<C> cs){
if (n==0 && cs.isEmpty()){return _This0;}
return new PathCore(n,PathAux.immCs(cs));
}
public static Path _parsePathCode(List<String>names){
if(names.isEmpty()){return null;}
String first=names.get(0);
if(!PathAux.isValidOuter(first)){return null;}
first = first.substring("This".length());
int n=0;
if(!first.isEmpty()){
n = Integer.parseInt(first);
}
List<String>tail=names.subList(1, names.size());
return instance(n,PathAux.sToC(tail));
}
private static final PathCore _This0 = new PathCore(0,Collections.emptyList());
final int outerN;
final List<C> cBar;
public boolean isCore() { return true; }
public Path popC(){return new PathCore(outerN,cBar.subList(0,cBar.size()-1));}
public Path pushC(C c){
List<C> newCBar = new ArrayList<>(cBar);
newCBar.add(c);
return new PathCore(outerN,PathAux.immCs(newCBar));
}
public List<C> getCBar(){return cBar;}
public Path setNewOuter(int n){return new PathCore(n,cBar);}
public int outerNumber(){return outerN;}
}
@Value @EqualsAndHashCode(callSuper=false)
class PathPrimitive extends Path{
public String toString() { return sugarVisitors.ToFormattedText.of(this);}//otherwise lombock overrides it
private PathPrimitive(String name) {this.name = name;}
final String name;
public boolean isPrimitive() {return true;}
public static Path _parsePrimitive(List<String> names){
if(names.size()!=1){return null;}
String name=names.get(0);
return _parsePrimitive(name);
}
public static Path _parsePrimitive(String name){
if(name.equals(_Void.name)){return _Void;}
if(name.equals(_Any.name)){return _Any;}
if(name.equals(_Library.name)){return _Library;}
return null;
}
static public final PathPrimitive _Void = new PathPrimitive("Void");
static public final PathPrimitive _Any = new PathPrimitive("Any");
static public final PathPrimitive _Library = new PathPrimitive("Library");
}
@Value @EqualsAndHashCode(callSuper=false)
class PathSugar extends Path{
public String toString() { return sugarVisitors.ToFormattedText.of(this);}//otherwise lombock overrides it
public static Path _instance(List<String> names){
for(String s:names){
if(!PathAux.isValidClassName(s)){
return null;
}
}
assert (names=Collections.unmodifiableList(names))!=null;//ok for testing efficiency
return new PathSugar(PathAux.sToC(names));
}
private PathSugar(List<C> names) {
this.names = names;
}
final List<C> names;
public List<C> sugarNames(){return names;}
}