package org.sahagin.runlib.srctreegen;

import org.sahagin.runlib.additionaltestdoc.AdditionalClassTestDoc;
import org.sahagin.runlib.additionaltestdoc.AdditionalMethodTestDoc;
import org.sahagin.runlib.additionaltestdoc.AdditionalPage;
import org.sahagin.runlib.additionaltestdoc.AdditionalTestDocs;
import org.sahagin.share.srctree.PageClass;
import org.sahagin.share.srctree.TestClass;
import org.sahagin.share.srctree.TestClassTable;
import org.sahagin.share.srctree.TestMethod;
import org.sahagin.share.srctree.TestMethodTable;

// If TestClass or TestMethod for the AdditionlTestDoc does not exist in the table,
// add them as sub TestClass or sub TestMethod.
// If already exists, override it's TestDoc value.
//
// - This class assumes class qualifiedName is unique
public class AdditionalTestDocsSetter {
    private TestClassTable rootClassTable;
    private TestClassTable subClassTable;
    private TestMethodTable rootMethodTable;
    private TestMethodTable subMethodTable;

    public AdditionalTestDocsSetter(TestClassTable rootClassTable, TestClassTable subClassTable,
            TestMethodTable rootMethodTable, TestMethodTable subMethodTable) {
        this.rootClassTable = rootClassTable;
        this.subClassTable = subClassTable;
        this.rootMethodTable = rootMethodTable;
        this.subMethodTable = subMethodTable;
    }

    public void set(AdditionalTestDocs testDocs) {
        // override old data
        for (int i = 0; i < testDocs.getClassTestDocs().size(); i++) {
            AdditionalClassTestDoc classTestDoc = testDocs.getClassTestDocs().get(i);
            setClass(classTestDoc.getQualifiedName(), classTestDoc.getTestDoc(),
                    classTestDoc.getDelegateToQualifiedName(), classTestDoc instanceof AdditionalPage);
        }
        for (int i = 0; i < testDocs.getMethodTestDocs().size(); i++) {
            AdditionalMethodTestDoc testDoc = testDocs.getMethodTestDocs().get(i);
            setMethod(testDoc);
        }
    }

    // return the newly set TestClass instance or already set instance.
    private TestClass setClass(String qualifiedName, String testDoc,
            String delegateToClassQualifiedName, boolean isPage) {
        for (TestClass testClass : subClassTable.getTestClasses()) {
            // class qualified name must be unique
            if (qualifiedName.equals(testClass.getQualifiedName())) {
                // override existing testDoc ( don't override other information)
                testClass.setTestDoc(testDoc);
                return testClass;
            }
        }

        for (TestClass testClass : rootClassTable.getTestClasses()) {
            // class qualified name must be unique
            if (qualifiedName.equals(testClass.getQualifiedName())) {
                // override existing testDoc ( don't override other information)
                testClass.setTestDoc(testDoc);
                return testClass;
            }
        }

        TestClass newClass;
        if (isPage) {
            newClass = new PageClass();
        } else {
            newClass = new TestClass();
        }
        newClass.setKey(qualifiedName);
        newClass.setQualifiedName(qualifiedName);
        newClass.setTestDoc(testDoc);
        newClass.setDelegateToTestClassKey(delegateToClassQualifiedName);
        subClassTable.addTestClass(newClass);
        return newClass;
    }

    // return the newly set TestMethod instance or already set instance.
    // - TestDoc of the same name and argument types method can be overridden
    private TestMethod setMethod(AdditionalMethodTestDoc testDoc) {
        String methodKey;
        if (testDoc.isOverloaded()) {
            methodKey = TestMethod.generateMethodKey(
                    testDoc.getClassQualifiedName(), testDoc.getSimpleName(), testDoc.getArgClassesStr());
        } else {
            methodKey = TestMethod.generateMethodKey(
                    testDoc.getClassQualifiedName(), testDoc.getSimpleName());
        }
        for (TestMethod testMethod : subMethodTable.getTestMethods()) {
            if (testMethod.getKey().equals(methodKey)) {
                // override existing testDoc ( don't override other information)
                testMethod.setTestDoc(testDoc.getTestDoc());
                return testMethod;
            }
        }
        for (TestMethod testMethod : rootMethodTable.getTestMethods()) {
            if (testMethod.getKey().equals(methodKey)) {
                // override existing testDoc ( don't override other information)
                testMethod.setTestDoc(testDoc.getTestDoc());
                return testMethod;
            }
        }

        TestMethod newMethod = new TestMethod();
        TestClass testClass = setClass(testDoc.getClassQualifiedName(), null, null, false);
        newMethod.setTestClassKey(testClass.getKey());
        newMethod.setTestClass(testClass);
        testClass.addTestMethod(newMethod);
        newMethod.setKey(methodKey);
        newMethod.setSimpleName(testDoc.getSimpleName());
        newMethod.setTestDoc(testDoc.getTestDoc());
        newMethod.setCaptureStyle(testDoc.getCaptureStyle());
        newMethod.setVariableLengthArgIndex(testDoc.getVariableLengthArgIndex());
        subMethodTable.addTestMethod(newMethod);
        return newMethod;
    }

}

@@ -1978,27 +1978,24 @@
       %7D%0A    
-%7D%0A%0A
     // retur
@@ -1995,70 +1995,426 @@
 / re
-turn the newly set TestClass instance or already set instance.
+solve delegate%0A        for (TestClass testClass: rootClassTable.getTestClasses()) %7B%0A            testClass.setDelegateToTestClass(%0A                    getTestClass(testClass.getDelegateToTestClassKey()));%0A        %7D%0A        for (TestClass testClass: subClassTable.getTestClasses()) %7B%0A            testClass.setDelegateToTestClass(%0A                    getTestClass(testClass.getDelegateToTestClassKey()));%0A        %7D%0A    %7D%0A
 %0A   
@@ -2432,19 +2432,23 @@
 stClass 
-s
+g
 et
+Test
 Class(St
@@ -2469,92 +2469,84 @@
 Name
-, String testDoc,%0A            String delegateToClassQualifiedName, boolean isPage) %7B
+) %7B%0A        if (qualifiedName == null) %7B%0A            return null;%0A        %7D%0A
 %0A   
@@ -2736,136 +2736,8 @@
 ) %7B%0A
-                // override existing testDoc ( don't override other information)%0A                testClass.setTestDoc(testDoc);%0A
     
@@ -2978,32 +2978,414 @@
 dName())) %7B%0A    
+            return testClass;%0A            %7D%0A        %7D%0A        return null;%0A    %7D%0A%0A    // return the newly set TestClass instance or already set instance.%0A    private TestClass setClass(String qualifiedName, String testDoc,%0A            String delegateToClassQualifiedName, boolean isPage) %7B%0A        TestClass testClass = getTestClass(qualifiedName);%0A        if (testClass != null) %7B%0A
             // o
@@ -3437,36 +3437,32 @@
 er information)%0A
-    
             test
@@ -3492,36 +3492,32 @@
 c);%0A            
-    
 return testClass
@@ -3514,38 +3514,24 @@
  testClass;%0A
-            %7D%0A
         %7D%0A%0A 

Resolve delegate