package org.testng.internal;

import org.testng.IClass;
import org.testng.IInstanceInfo;
import org.testng.IObjectFactory;
import org.testng.ITestContext;
import org.testng.ITestObjectFactory;
import org.testng.TestNGException;
import org.testng.annotations.IAnnotation;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.internal.annotations.AnnotationHelper;
import org.testng.internal.annotations.IAnnotationFinder;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlTest;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This class creates an ITestClass from a test class.
 *
 * @author <a href="mailto:cedric@beust.com">Cedric Beust</a>
 */
public class TestNGClassFinder extends BaseClassFinder {
  private ITestContext m_testContext = null;
  private Map<Class, List<Object>> m_instanceMap = Maps.newHashMap();

  public TestNGClassFinder(ClassInfoMap cim,
                           Map<Class, List<Object>> instanceMap,
                           XmlTest xmlTest,
                           IConfiguration configuration,
                           ITestContext testContext)
  {
    m_testContext = testContext;

    if(null == instanceMap) {
      instanceMap= Maps.newHashMap();
    }

    IAnnotationFinder annotationFinder = configuration.getAnnotationFinder();
    ITestObjectFactory objectFactory = configuration.getObjectFactory();

    //
    // Find all the new classes and their corresponding instances
    //
    Set<Class<?>> allClasses= cim.getClasses();

    //very first pass is to find ObjectFactory, can't create anything else until then
    if(objectFactory == null) {
      objectFactory = new ObjectFactoryImpl();
      outer:
      for (Class cls : allClasses) {
        try {
          if (null != cls) {
            for (Method m : cls.getMethods()) {
              IAnnotation a = annotationFinder.findAnnotation(m,
                  org.testng.annotations.IObjectFactoryAnnotation.class);
              if (null != a) {
                if (!ITestObjectFactory.class.isAssignableFrom(m.getReturnType())) {
                  throw new TestNGException("Return type of " + m + " is not IObjectFactory");
                }
                try {
                  Object instance = cls.newInstance();
                  if (m.getParameterTypes().length > 0 && m.getParameterTypes()[0].equals(ITestContext.class)) {
                    objectFactory = (ITestObjectFactory) m.invoke(instance, testContext);
                  } else {
                    objectFactory = (ITestObjectFactory) m.invoke(instance);
                  }
                  break outer;
                }
                catch (Exception ex) {
                  throw new TestNGException("Error creating object factory", ex);
                }
              }
            }
          }
        } catch (NoClassDefFoundError e) {
          Utils.log("[TestNGClassFinder]", 1, "Unable to read methods on class " + cls.getName()
              + " - unable to resolve class reference " + e.getMessage());

          for (XmlClass xmlClass : xmlTest.getXmlClasses()) {
            if (xmlClass.loadClasses() && xmlClass.getName().equals(cls.getName())) {
              throw e;
            }
          }

        }
      }
    }

    for(Class cls : allClasses) {
      if((null == cls)) {
        ppp("FOUND NULL CLASS IN FOLLOWING ARRAY:");
        int i= 0;
        for(Class c : allClasses) {
          ppp("  " + i + ": " + c);
        }

        continue;
      }

      if(isTestNGClass(cls, annotationFinder)) {
        List allInstances= instanceMap.get(cls);
        Object thisInstance= (null != allInstances) ? allInstances.get(0) : null;

        // If annotation class and instances are abstract, skip them
        if ((null == thisInstance) && Modifier.isAbstract(cls.getModifiers())) {
          Utils.log("", 5, "[WARN] Found an abstract class with no valid instance attached: " + cls);
          continue;
        }

        IClass ic= findOrCreateIClass(m_testContext, cls, cim.getXmlClass(cls), thisInstance,
            xmlTest, annotationFinder, objectFactory);
        if(null != ic) {
          Object[] theseInstances = ic.getInstances(false);
          if (theseInstances.length == 0) {
            theseInstances = ic.getInstances(true);
          }
          Object instance= theseInstances[0];
          putIClass(cls, ic);

          ConstructorOrMethod factoryMethod =
            ClassHelper.findDeclaredFactoryMethod(cls, annotationFinder);
          if (null != factoryMethod) {
            FactoryMethod fm = new FactoryMethod( /* cls, */
              factoryMethod,
              instance,
              xmlTest,
              annotationFinder,
              m_testContext);
            ClassInfoMap moreClasses = new ClassInfoMap();

            {
//            ppp("INVOKING FACTORY " + fm + " " + this.hashCode());
              Object[] instances= fm.invoke();

              //
              // If the factory returned IInstanceInfo, get the class from it,
              // otherwise, just call getClass() on the returned instances
              //
              if (instances.length > 0) {
                if (instances[0] != null) {
                  Class elementClass = instances[0].getClass();
                  if(IInstanceInfo.class.isAssignableFrom(elementClass)) {
                    for(Object o : instances) {
                      IInstanceInfo ii = (IInstanceInfo) o;
                      addInstance(ii.getInstanceClass(), ii.getInstance());
                      moreClasses.addClass(ii.getInstanceClass());
                    }
                  }
                  else {
                    for (int i = 0; i < instances.length; i++) {
                      Object o = instances[i];
                      if (o == null) {
                        throw new TestNGException("The factory " + fm + " returned a null instance" +
                            "at index " + i);
                      } else {
                        addInstance(o.getClass(), o);
                        if(!classExists(o.getClass())) {
                          moreClasses.addClass(o.getClass());
                        }
                      }
                    }
                  }
                }
              }
            }

            if(moreClasses.getSize() > 0) {
              TestNGClassFinder finder=
                new TestNGClassFinder(moreClasses,
                    m_instanceMap,
                    xmlTest,
                    configuration,
                    m_testContext);

              IClass[] moreIClasses= finder.findTestClasses();
              for(IClass ic2 : moreIClasses) {
                putIClass(ic2.getRealClass(), ic2);
              }
            } // if moreClasses.size() > 0
          }
        } // null != ic
      } // if not TestNG class
      else {
        Utils.log("TestNGClassFinder", 3, "SKIPPING CLASS " + cls + " no TestNG annotations found");
      }
    } // for

    //
    // Add all the instances we found to their respective IClasses
    //
    for(Class c : m_instanceMap.keySet()) {
      List<Object> instances= m_instanceMap.get(c);
      for(Object instance : instances) {
        IClass ic= getIClass(c);
        if(null != ic) {
          ic.addInstance(instance);
        }
      }
    }
  }

  /**
   * @returns true if this class contains TestNG annotations (either on itself
   * or on a superclass).
   */
  public static boolean isTestNGClass(Class c, IAnnotationFinder annotationFinder) {
    Class[] allAnnotations= AnnotationHelper.getAllAnnotations();
    Class cls = c;

    try {
      for(Class annotation : allAnnotations) {

        for (cls = c; cls != null; cls = cls.getSuperclass()) {
          // Try on the methods
          for (Method m : cls.getMethods()) {
            IAnnotation ma= annotationFinder.findAnnotation(m, annotation);
            if(null != ma) {
              return true;
            }
          }

          // Try on the class
          IAnnotation a= annotationFinder.findAnnotation(cls, annotation);
          if(null != a) {
            return true;
          }

          // Try on the constructors
          for (Constructor ctor : cls.getConstructors()) {
            IAnnotation ca= annotationFinder.findAnnotation(ctor, annotation);
            if(null != ca) {
              return true;
            }
          }
        }
      }

      return false;

    } catch (NoClassDefFoundError e) {
      Utils.log("[TestNGClassFinder]", 1,
          "Unable to read methods on class " + cls.getName()
          + " - unable to resolve class reference " + e.getMessage());
      return false;
    }
  }

  private void addInstance(Class clazz, Object o) {
    List<Object> list= m_instanceMap.get(clazz);

    if(null == list) {
      list= Lists.newArrayList();
      m_instanceMap.put(clazz, list);
    }

    list.add(o);
  }

  public static void ppp(String s) {
    System.out.println("[TestNGClassFinder] " + s);
  }

}
