package org.testng.xml;

import org.testng.TestNG;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.internal.AnnotationTypeEnum;
import org.testng.reporters.XMLStringBuffer;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * This class describes the tag &lt;test&gt;  in testng.xml.
 * 
 * @author <a href = "mailto:cedric&#64;beust.com">Cedric Beust</a>
 * @author <a href = 'mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a>
 */
public class XmlTest implements Serializable, Cloneable {
  public static int DEFAULT_TIMEOUT_MS = Integer.MAX_VALUE;

  private XmlSuite m_suite;
  private String m_name = TestNG.DEFAULT_COMMAND_LINE_SUITE_NAME;
  private Integer m_verbose = XmlSuite.DEFAULT_VERBOSE;
  private Boolean m_isJUnit = null;
  private int m_threadCount= -1;

  private List<XmlClass> m_xmlClasses = Lists.newArrayList();
  
  private List<String> m_includedGroups = Lists.newArrayList();
  private List<String> m_excludedGroups = Lists.newArrayList();

  private Map<String, List<String>> m_metaGroups = Maps.newHashMap();
  private Map<String, String> m_parameters = Maps.newHashMap();
  private String m_parallel;
  
  /** */
  private AnnotationTypeEnum m_annotations;
  
  // BeanShell expression
  private String m_expression;
  private List<XmlMethodSelector> m_methodSelectors = Lists.newArrayList();
  // test level packages
  private List<XmlPackage> m_xmlPackages = Lists.newArrayList();
  
  private String m_timeOut;
  private Boolean m_skipFailedInvocationCounts = XmlSuite.DEFAULT_SKIP_FAILED_INVOCATION_COUNTS;
  private Map<String, List<Integer>> m_failedInvocationNumbers = null; // lazily initialized

  public static String DEFAULT_PRESERVE_ORDER = "false";
  private String m_preserveOrder = DEFAULT_PRESERVE_ORDER;

  /**
   * Constructs a <code>XmlTest</code> and adds it to suite's list of tests. 
   *
   * @param suite the parent suite.
   */
  public XmlTest(XmlSuite suite) {
    m_suite = suite;
    m_suite.getTests().add(this);
  }

  // For YAML
  public XmlTest() {
  }

  public void setXmlPackages(List<XmlPackage> packages) {
    m_xmlPackages = packages;
  }
  
  public List<XmlPackage> getXmlPackages() {
    return m_xmlPackages;
  }

  // For YAML
  public List<XmlPackage> getPackages() {
    return getPackages();
  }

  // For YAML
  public void setPackages(List<XmlPackage> p) {
    setXmlPackages(p);
  }

  public List<XmlMethodSelector> getMethodSelectors() {
    return m_methodSelectors;
  }

  public void setMethodSelectors(List<XmlMethodSelector> methodSelectors) {
    m_methodSelectors = methodSelectors;
  }
  
  /**
   * Returns the suite this test is part of.
   * @return the suite this test is part of.
   */
  public XmlSuite getSuite() {
    return m_suite;
  }
  
  /**
   * @return Returns the includedGroups.
   */
  public List<String> getIncludedGroups() {
    return m_includedGroups;
  }
  
  /**
   * Sets the XML Classes.
   * @param classes The classes to set.
   * @deprecated use setXmlClasses
   */
  @Deprecated
  public void setClassNames(List<XmlClass> classes) {
    m_xmlClasses = classes;
  }
    
  /**
   * @return Returns the classes.
   */
  public List<XmlClass> getXmlClasses() {
    return m_xmlClasses;
  }

  // For YAML
  public List<XmlClass> getClasses() {
    return getXmlClasses();
  }

  // For YAML
  public void setClasses(List<XmlClass> c) {
    setXmlClasses(c);
  }

  /**
   * Sets the XML Classes.
   * @param classes The classes to set.
   */
  public void setXmlClasses(List<XmlClass> classes) {
    m_xmlClasses = classes;
  }
  
  /**
   * @return Returns the name.
   */
  public String getName() {
    return m_name;
  }
  
  /**
   * @param name The name to set.
   */
  public void setName(String name) {
    m_name = name;
  }

  /**
   * @param v
   */
  public void setVerbose(int v) {
    m_verbose = new Integer( v);
  }

  public int getThreadCount() {
    return m_threadCount > 0 ? m_threadCount : getSuite().getThreadCount();
  }

  public void setThreadCount(int threadCount) {
    m_threadCount = threadCount;
  }
  
  /**
   * @param g
   */
  public void setIncludedGroups(List<String> g) {
    m_includedGroups = g;
  }

  /**
   * @param g The excludedGrousps to set.
   */
  public void setExcludedGroups(List<String> g) {
    m_excludedGroups = g;
  }

  /**
   * @return Returns the excludedGroups.
   */
  public List<String> getExcludedGroups() {
    return m_excludedGroups;
  }
  
  /**
   * @return Returns the verbose.
   */
  public int getVerbose() {
    Integer result = m_verbose;
    if (null == result || XmlSuite.DEFAULT_VERBOSE.equals(m_verbose)) {
      result = m_suite.getVerbose();
    }
    
    if (null != result) {
      return result.intValue();
    } else {
      return 1;
    }
  }
  /**
   * @return Returns the isJUnit.
   */
  public boolean isJUnit() {
    Boolean result = m_isJUnit;
    if (null == result || XmlSuite.DEFAULT_JUNIT.equals(result)) {
      result = m_suite.isJUnit();
    }
    
    return result;
  }

  /**
   * @param isJUnit The isJUnit to set.
   */
  public void setJUnit(boolean isJUnit) {
    m_isJUnit = isJUnit;
  }

  // For YAML
  public void setJunit(boolean isJUnit) {
    setJUnit(isJUnit);
  }

  public void setSkipFailedInvocationCounts(boolean skip) {
    m_skipFailedInvocationCounts = skip;
  }
  
  /**
   * @return Returns the isJUnit.
   */
  public boolean skipFailedInvocationCounts() {
    Boolean result = m_skipFailedInvocationCounts;
    if (null == result) {
      result = m_suite.skipFailedInvocationCounts();
    }
    
    return result;
  }
  
  public void addMetaGroup(String name, List<String> metaGroup) {
    m_metaGroups.put(name, metaGroup);
  }

  // For YAML
  public void setMetaGroups(Map<String, List<String>> metaGroups) {
    m_metaGroups = metaGroups;
  }

  /**
   * @return Returns the metaGroups.
   */
  public Map<String, List<String>> getMetaGroups() {
    return m_metaGroups;
  }
  
  /**
   * @param parameters
   */
  public void setParameters(Map<String, String> parameters) {
    m_parameters = parameters;
  }
  
  public void addParameter(String key, String value) {
    m_parameters.put(key, value);
  }
  
  public String getParameter(String name) {
    String result = m_parameters.get(name);
    if (null == result) {
      result = m_suite.getParameter(name);
    }
    
    return result;
  }

  /**
   * Returns a merge of the the test parameters and its parent suite parameters. Test parameters 
   * have precedence over suite parameters.
   * 
   * @return a merge of the the test parameters and its parent suite parameters.
   */
  public Map<String, String> getParameters() {
    Map<String, String> result = Maps.newHashMap();
    Map<String, String> parameters = getSuite().getParameters();
    for (Map.Entry<String, String> parameter : parameters.entrySet()) {
      result.put(parameter.getKey(), parameter.getValue());
    }
    for (String key : m_parameters.keySet()) {
      result.put(key, m_parameters.get(key));
    }
    return result;
  }

  /**
   * @return the parameters defined on this <test> tag only
   */
  public Map<String, String> getTestParameters() {
    return m_parameters;
  }

  public void setParallel(String parallel) {
    m_parallel = parallel;
  }
  
  public String getParallel() {
    String result = null;
    if (null != m_parallel || XmlSuite.DEFAULT_PARALLEL.equals(m_parallel)) {
      result = m_parallel;
    }
    else {
      result = m_suite.getParallel();
    }
    
    return result;
  }
  
  public String getTimeOut() {
    String result = null;
    if (null != m_timeOut) {
      result = m_timeOut;
    }
    else {
      result = m_suite.getTimeOut();
    }
      
    return result;
  }
  
  public long getTimeOut(long def) {
    long result = def;
    if (getTimeOut() != null) {
        result = new Long(getTimeOut()).longValue();
    }
     
    return result;
  }
  
  public void setTimeOut(long timeOut) {
      m_timeOut = new Long(timeOut).toString();
  }
  
  public String getAnnotations() {
    return null != m_annotations ? m_annotations.toString() : m_suite.getAnnotations();
  }
  
  public void setAnnotations(String annotations) {
    m_annotations = AnnotationTypeEnum.valueOf(annotations);
  }

  public void setBeanShellExpression(String expression) {
    m_expression = expression;
  }
  
  public String getExpression() {
    return m_expression;
  }

  public String toXml(String indent) {
    XMLStringBuffer xsb = new XMLStringBuffer(indent);
    Properties p = new Properties();
    p.setProperty("name", getName());
    p.setProperty("junit", m_isJUnit != null ? m_isJUnit.toString() : "false");
    if (null != m_parallel && !"".equals(m_parallel)) {
      p.setProperty("parallel", m_parallel);
    }
    if (null != m_verbose) {
      p.setProperty("verbose", m_verbose.toString());
    }
    if (null != m_annotations) {
      p.setProperty("annotations", m_annotations.toString());
    }
    if (null != m_timeOut) {
      p.setProperty("time-out", m_timeOut.toString());
    }
    if (m_preserveOrder != null) {
      p.setProperty("preserve-order", m_preserveOrder.toString());
    }
    
    xsb.push("test", p);
    
    
    if (null != getMethodSelectors() && !getMethodSelectors().isEmpty()) {
      xsb.push("method-selectors");
      for (XmlMethodSelector selector: getMethodSelectors()) {
        xsb.getStringBuffer().append(selector.toXml(indent + "    "));
      }
      
      xsb.pop("method-selectors");
    }
    
    // parameters
    if (!m_parameters.isEmpty()) {
      for(Map.Entry<String, String> para: m_parameters.entrySet()) {
        Properties paramProps= new Properties();
        paramProps.setProperty("name", para.getKey());
        paramProps.setProperty("value", para.getValue());
        xsb.addEmptyElement("parameter", paramProps); // BUGFIX: TESTNG-27
      }
    }
    
    // groups
    if (!m_metaGroups.isEmpty() || !m_includedGroups.isEmpty() || !m_excludedGroups.isEmpty()) {
      xsb.push("groups");
      
      // define
      for (String metaGroupName: m_metaGroups.keySet()) {
        Properties metaGroupProp= new Properties();
        metaGroupProp.setProperty("name",  metaGroupName);
        
        xsb.push("define", metaGroupProp);
        
        for (String groupName: m_metaGroups.get(metaGroupName)) {
          Properties includeProps = new Properties();
          includeProps.setProperty("name", groupName);
          
          xsb.addEmptyElement("include", includeProps);
        }
        
        xsb.pop("define");
      }
      
      if (!m_includedGroups.isEmpty() || !m_excludedGroups.isEmpty()) {
        xsb.push("run");
        
        for (String includeGroupName: m_includedGroups) {
          Properties includeProps = new Properties();
          includeProps.setProperty("name", includeGroupName);
          
          xsb.addEmptyElement("include", includeProps);
        }
        
        for (String excludeGroupName: m_excludedGroups) {
          Properties excludeProps = new Properties();
          excludeProps.setProperty("name", excludeGroupName);
          
          xsb.addEmptyElement("exclude", excludeProps);
        }
        
        xsb.pop("run");
      }
      
      xsb.pop("groups");
    }
    
    
    // Don't call getXmlPackages() cause you will retrieve the suite packages too
    if (null != m_xmlPackages && !m_xmlPackages.isEmpty()) {
      xsb.push("packages");
      
      for (XmlPackage pack: m_xmlPackages) {
        xsb.getStringBuffer().append(pack.toXml("      "));
      }
      
      xsb.pop("packages");
    }
    
    // classes
    if (null != getXmlClasses() && !getXmlClasses().isEmpty()) {
      xsb.push("classes");
      for (XmlClass cls : getXmlClasses()) {
        xsb.getStringBuffer().append(cls.toXml(indent + "    "));
      }
      xsb.pop("classes");
    }
    
    xsb.pop("test");
    
    return xsb.toXML();
  }
  
  @Override
  public String toString() {
    StringBuffer result = new StringBuffer("[Test: \"" + m_name + "\"")
      .append(" verbose:" + m_verbose);
    
    result.append("[parameters:");
    for (String k : m_parameters.keySet()) {
      String v = m_parameters.get(k);
      result.append(k + "=>" + v);
    }
    
    result.append("]");
    result.append("[metagroups:");
    for (String g : m_metaGroups.keySet()) {
      List<String> mg = m_metaGroups.get(g);
      result.append(g).append("=");
      for (String n : mg) {
        result.append(n).append(",");
      }
    }
    result.append("] ");
    
    result.append("[included: ");
    for (String g : m_includedGroups) {
      result.append(g).append(" ");
    }
    result.append("]");
    
    result.append("[excluded: ");
    for (String g : m_excludedGroups) {
      result.append(g).append("");
    }
    result.append("] ");
    
    result.append(" classes:");
    for (XmlClass cl : m_xmlClasses) {
      result.append(cl).append(" ");
    }
    
    result.append("] ");
    
    return result.toString();
  }
  
  static void ppp(String s) {
    System.out.println("[XmlTest] " + s);
  }
  
  /**
   * Clone the <TT>source</TT> <CODE>XmlTest</CODE> by including: 
   * - test attributes
   * - groups definitions
   * - parameters
   * 
   * The &lt;classes&gt; sub element is ignored for the moment.
   * 
   * @return a clone of the current XmlTest
   */
  @Override
  public Object clone() {
    XmlTest result = new XmlTest(getSuite());
    
    result.setName(getName());
    result.setAnnotations(getAnnotations());
    result.setIncludedGroups(getIncludedGroups());
    result.setExcludedGroups(getExcludedGroups());
    result.setJUnit(isJUnit());
    result.setParallel(getParallel());
    result.setVerbose(getVerbose());
    result.setParameters(getParameters());
    result.setXmlPackages(getXmlPackages());
    
    Map<String, List<String>> metagroups = getMetaGroups();
    for (Map.Entry<String, List<String>> group: metagroups.entrySet()) {
      result.addMetaGroup(group.getKey(), group.getValue());
    }
    
    return result;
  }

  /**
   * Convenience method to cache the ordering numbers for methods.
   */
  public List<Integer> getInvocationNumbers(String method) {
    if (m_failedInvocationNumbers == null) {
      m_failedInvocationNumbers = Maps.newHashMap();
      for (XmlClass c : getXmlClasses()) {
        for (XmlInclude xi : c.getIncludedMethods()) {
          List<Integer> invocationNumbers = xi.getInvocationNumbers();
          if (invocationNumbers.size() > 0) {
            String methodName = c.getName() + "." + xi.getName();
            m_failedInvocationNumbers.put(methodName, invocationNumbers);
          }
        }
      }
    }

    List<Integer> result = m_failedInvocationNumbers.get(method);
    if (result == null) {
      // Don't use emptyList here since this list might end up receiving values if
      // the test run fails.
      return Lists.newArrayList();
    } else {
      return result;
    }
  }

  public void setPreserveOrder(String preserveOrder) {
    m_preserveOrder = preserveOrder;
  }

  public String getPreserveOrder() {
    return m_preserveOrder;
  }

  public void setSuite(XmlSuite result) {
    m_suite = result;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result
        + ((m_excludedGroups == null) ? 0 : m_excludedGroups.hashCode());
    result = prime * result
        + ((m_expression == null) ? 0 : m_expression.hashCode());
    result = prime
        * result
        + ((m_failedInvocationNumbers == null) ? 0 : m_failedInvocationNumbers
            .hashCode());
    result = prime * result
        + ((m_includedGroups == null) ? 0 : m_includedGroups.hashCode());
    result = prime * result + ((m_isJUnit == null) ? 0 : m_isJUnit.hashCode());
    result = prime * result
        + ((m_metaGroups == null) ? 0 : m_metaGroups.hashCode());
    result = prime * result
        + ((m_methodSelectors == null) ? 0 : m_methodSelectors.hashCode());
    result = prime * result + ((m_name == null) ? 0 : m_name.hashCode());
    result = prime * result
        + ((m_parallel == null) ? 0 : m_parallel.hashCode());
    result = prime * result
        + ((m_parameters == null) ? 0 : m_parameters.hashCode());
    result = prime * result
        + ((m_preserveOrder == null) ? 0 : m_preserveOrder.hashCode());
    result = prime
        * result
        + ((m_skipFailedInvocationCounts == null) ? 0
            : m_skipFailedInvocationCounts.hashCode());
    result = prime * result + m_threadCount;
    result = prime * result + ((m_timeOut == null) ? 0 : m_timeOut.hashCode());
    result = prime * result + ((m_verbose == null) ? 0 : m_verbose.hashCode());
    result = prime * result
        + ((m_xmlClasses == null) ? 0 : m_xmlClasses.hashCode());
    result = prime * result
        + ((m_xmlPackages == null) ? 0 : m_xmlPackages.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    XmlTest other = (XmlTest) obj;
    if (m_excludedGroups == null) {
      if (other.m_excludedGroups != null)
        return false;
    } else if (!m_excludedGroups.equals(other.m_excludedGroups))
      return false;
    if (m_expression == null) {
      if (other.m_expression != null)
        return false;
    } else if (!m_expression.equals(other.m_expression))
      return false;
    if (m_failedInvocationNumbers == null) {
      if (other.m_failedInvocationNumbers != null)
        return false;
    } else if (!m_failedInvocationNumbers
        .equals(other.m_failedInvocationNumbers))
      return false;
    if (m_includedGroups == null) {
      if (other.m_includedGroups != null)
        return false;
    } else if (!m_includedGroups.equals(other.m_includedGroups))
      return false;
    if (m_isJUnit == null) {
      if (other.m_isJUnit != null && ! other.m_isJUnit.equals(XmlSuite.DEFAULT_JUNIT))
        return false;
    } else if (!m_isJUnit.equals(other.m_isJUnit))
      return false;
    if (m_metaGroups == null) {
      if (other.m_metaGroups != null)
        return false;
    } else if (!m_metaGroups.equals(other.m_metaGroups))
      return false;
    if (m_methodSelectors == null) {
      if (other.m_methodSelectors != null)
        return false;
    } else if (!m_methodSelectors.equals(other.m_methodSelectors))
      return false;
    if (m_name == null) {
      if (other.m_name != null)
        return false;
    } else if (!m_name.equals(other.m_name))
      return false;
    if (m_parallel == null) {
      if (other.m_parallel != null)
        return false;
    } else if (!m_parallel.equals(other.m_parallel))
      return false;
    if (m_parameters == null) {
      if (other.m_parameters != null)
        return false;
    } else if (!m_parameters.equals(other.m_parameters))
      return false;
    if (m_preserveOrder == null) {
      if (other.m_preserveOrder != null)
        return false;
    } else if (!m_preserveOrder.equals(other.m_preserveOrder))
      return false;
    if (m_skipFailedInvocationCounts == null) {
      if (other.m_skipFailedInvocationCounts != null)
        return false;
    } else if (!m_skipFailedInvocationCounts
        .equals(other.m_skipFailedInvocationCounts))
      return false;
    if (m_threadCount != other.m_threadCount)
      return false;
    if (m_timeOut == null) {
      if (other.m_timeOut != null)
        return false;
    } else if (!m_timeOut.equals(other.m_timeOut))
      return false;
    if (m_verbose == null) {
      if (other.m_verbose != null)
        return false;
    } else if (!m_verbose.equals(other.m_verbose))
      return false;
    if (m_xmlClasses == null) {
      if (other.m_xmlClasses != null)
        return false;
    } else if (!m_xmlClasses.equals(other.m_xmlClasses))
      return false;
    if (m_xmlPackages == null) {
      if (other.m_xmlPackages != null)
        return false;
    } else if (!m_xmlPackages.equals(other.m_xmlPackages))
      return false;
    return true;
  }
}
