package de.dhbwstuttgart.syntaxtree;
import java.util.*;


import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.typecheck.JavaClassName;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;


public class SourceFile extends SyntaxTreeNode{
  private String pkgName;

  private List<ClassOrInterface> KlassenVektor = new ArrayList<>();
    private List<JavaClassName> imports;

    /**
     * Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei.
     * SourceFile stellt dabei den Wurzelknoten des Syntaxbaumes dar.
     */
  public SourceFile(String pkgName,List<ClassOrInterface> classDefinitions,List<JavaClassName> imports){
    super(new NullToken());
    this.KlassenVektor = classDefinitions;
    if(pkgName != null){
      this.pkgName = pkgName;
    }
    if(imports != null){
      this.imports = imports;
    }
  }
  
  public SourceFile(List<ClassOrInterface> classDefinitions){
    this(null, classDefinitions, null);
  }
  
  public SourceFile(String pkgName, List<ClassOrInterface> classDefinitions){
    this(pkgName, classDefinitions, null);
  }
  
  public SourceFile(List<ClassOrInterface> classDefinitions, List<JavaClassName> imports){
    this(null, classDefinitions, imports);
  }
  
  public String getPkgName(){
    return this.pkgName;
  }

  // Get imports (to test implementation)
  public List<JavaClassName> getImports(){
    return this.imports;
  }

  public ConstraintSet getConstraints(TypeInferenceInformation info) {
    ConstraintSet ret = new ConstraintSet();
    for (ClassOrInterface cl : this.KlassenVektor) {
      ret.addAll(cl.getConstraints(info));
    }
    return ret;
  }

  public TypeInferenceInformation getTypeInferenceInformation(List<SourceFile> sourceFiles){
    Set<ClassOrInterface> classes = new HashSet<>();
    for(SourceFile sourceFile : sourceFiles){
      classes.addAll(sourceFile.KlassenVektor);
    }

    return new TypeInferenceInformation(classes);
  }

  public List<ClassOrInterface> getClasses() {
    return KlassenVektor;
  }
}