import AST.*;
import java.util.*;

public class TestNestedDotList {

  private static final int AN = 10;
  private static final int BN = 10;
  private static final int FN = 100;

  private static final String PACKAGE = "p";
  private static final String FIELD = "f";

  public static void main(String[] args) {
    Prog p = createAST(2);
    String tree = p.printTree();
    System.out.println("Tree: " + tree);
  }

  public static Prog createAST(int level) {
    ASTNode[] classes = new ASTNode[AN];
    for (int i = 0; i < AN; i++) {
      classes[i] = createClass(level, "A" + i);
    }
    return new Prog(new AST.List().add(new CompUnit(PACKAGE,new AST.List(classes))));
  }

  private static ClassDecl createClass(int level, String className) {
    ASTNode[] decls = new ASTNode[BN+1];
    decls[0] = new FieldDecl(new ParseName(className), FIELD, 
        parseDots(PACKAGE + "." + className + "." + FIELD));
    for (int i = 1; i < BN+1; i++) {
      decls[i] = createInnerClass(level, className, "B" + i);
    }
    return new ClassDecl(className, new ParseName("Object"), new AST.List(decls));
  }

  private static MemberClassDecl createInnerClass(int level, String outerClassName, String innerClassName) {
    ASTNode[] fields = new ASTNode[FN];
    for (int i = 0; i < FN; i++) {
      fields[i] = createInnerField(level, outerClassName, FIELD + i);
    }
    return new MemberClassDecl(new ClassDecl(innerClassName, new ParseName("Object"), new AST.List(fields)));
  }

  private static FieldDecl createInnerField(int level, String outerClassName, String innerFieldName) {
    return new FieldDecl(new ParseName(outerClassName), innerFieldName, 
        parseDots(PACKAGE + "." + outerClassName + levelToStr(level,FIELD)));
  }

  private static String levelToStr(int level, String fieldName) {
    StringBuffer buf = new StringBuffer();
    for (int i = 1; i <= level; i++) {
      buf.append("." + fieldName);
    }
    return buf.toString();
  }

  private static Name parseDots(String list) {
    Stack<Name> stack = new Stack<Name>();
    StringTokenizer tok = new StringTokenizer(list, ".");
    while (tok.hasMoreTokens()) {
      stack.push(new ParseName(tok.nextToken()));
    }
    while (stack.size() > 1) { 
      Name right = stack.pop();
      Name left = stack.pop();
      stack.push(new Dot("dot", left, right));
    }
    return stack.pop();
  }

}
