/*********************************************************************
 * Copyright (c) 2004, 2007 Boeing
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Boeing - initial API and implementation
 **********************************************************************/

package org.eclipse.osee.ote.core;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.eclipse.osee.framework.jdk.core.persistence.Xmlizable;
import org.eclipse.osee.framework.jdk.core.persistence.XmlizableStream;
import org.eclipse.osee.framework.jdk.core.type.OseeCoreException;
import org.eclipse.osee.framework.jdk.core.util.xml.Jaxp;
import org.eclipse.osee.framework.jdk.core.util.xml.XMLStreamWriterUtil;
import org.eclipse.osee.framework.logging.OseeLog;
import org.eclipse.osee.ote.core.enums.PromptResponseType;
import org.eclipse.osee.ote.core.environment.EnvironmentTask;
import org.eclipse.osee.ote.core.environment.TestEnvironment;
import org.eclipse.osee.ote.core.environment.interfaces.ICancelTimer;
import org.eclipse.osee.ote.core.environment.interfaces.IExecutionUnitManagement;
import org.eclipse.osee.ote.core.environment.interfaces.IScriptControl;
import org.eclipse.osee.ote.core.environment.interfaces.ITestEnvironmentAccessor;
import org.eclipse.osee.ote.core.environment.interfaces.ITestLogger;
import org.eclipse.osee.ote.core.environment.interfaces.ITestStation;
import org.eclipse.osee.ote.core.environment.interfaces.ITimeout;
import org.eclipse.osee.ote.core.environment.interfaces.ITimerControl;
import org.eclipse.osee.ote.core.log.record.RequirementRecord;
import org.eclipse.osee.ote.core.log.record.TestCaseRecord;
import org.eclipse.osee.ote.core.log.record.TestDescriptionRecord;
import org.eclipse.osee.ote.core.log.record.TestRecord;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * TestCase is the abstract base class for all test cases. This class provides the interfaces necessary for a TestCase
 * to be part of a {@link org.eclipse.osee.ote.core.TestScript TestScript}.
 * <p>
 * The TestCase class contains the following information:
 * <ul>
 * <li><b>Standalone</b> - This is used to determine if a TestCase can be used in a selective run list.
 * <ul>
 * <li><b>true</b> - The TestCase runs as expected regardless of order.
 * <li><b>false</b> - The TestCase must be run in a given order with other test cases to work as expected.
 * </ul>
 * <li><b>Test Case Number</b> - A serial number automatically assigned at the time of construction.
 * <li><b>Tracability</b> - The requirements that are tested by this TestCase.
 * </ul>
 * <p>
 * When building a new TestCase object it is important to remember that the object contains information describing the
 * test case in addition to the run time code. It is also important to understand that the when writing classes which
 * within a TestScript that the object must be instantiated (typically done in the constructor) with a reference to the
 * TestScript it is within or else it will not be executed.
 * <p>
 * The following sample should be followed closely when building TestCase objects. <br>
 * <br>
 * <code>
 * public class OipCase extends TestCase {
 * 		<ul style="list-style: none">
 * <li>		public OipCase(TestScript parent) {
 * 			<ul style="list-style: none">
 * <li>			</code><i>Use <b>one</b> of the following constructors based on if this TestCase is standalone</i><code>
 * <li>			super(parent);</code> <i>Standalone defaulted to <b>false</b></i><code>
 * <li>			super(parent, true);</code><i>Standalone explicitly set to <b>true</b></i><code>
 * <li>
 * <li>			</code><i>All requirements tested in the test case should be noted here with the </i>
 * <code>{@link org.eclipse.osee.ote.core.TestCase#addTracability(String) addTracability}</code><i> method.</i> <code>
 * 			</ul>
 * <li>		}
 * <li>
 * <li>		</code><i><b>Note:</b>It is very important that </i><code>doTestCase</code><i> always has the </i>
 * <code>throws InterrupedException</code><i> in the method declaration. The ability to abort a script relies on this
 * statement, and without it many calls would have to be wrapped with a try/catch block.</i><code>
 * <li>		public void doTestCase(ITestEnvironmentAccessor environment, ITestLogger logger) throws InterruptedException {
 * 			<ul style="list-style: none">
 * <li>			</code><i>Place all of the runtime code for the test case here.</i><code>
 * 			</ul>
 * <li>		}
 * 		</ul>
 * }
 * </code>
 *
 * @see org.eclipse.osee.ote.core.TestScript
 * @author Ryan D. Brooks
 * @author Robert A. Fisher
 */
public abstract class TestCase implements ITestEnvironmentAccessor, Xmlizable, XmlizableStream {
   protected ITestLogger logger;
   private final ITestEnvironmentAccessor environment;
   private final boolean standAlone;
   private final WeakReference<TestScript> testScript;
   private final TestDescriptionRecord testDescription;
   @JsonProperty
   public int number;
   protected List<RequirementRecord> traceability = new ArrayList<>();

   public TestCase(TestScript testScript) {
      this(testScript, false);
   }

   public TestCase(TestScript testScript, boolean standAlone) {
      this(testScript, standAlone, true);
   }

   protected TestCase(TestScript testScript, boolean standAlone, boolean addToRunList) {
      super();
      this.testDescription = new TestDescriptionRecord(testScript.getTestEnvironment());
      this.standAlone = standAlone;
      if (addToRunList) {
         this.number = testScript.addTestCase(this);
      }
      this.testScript = new WeakReference<>(testScript);
      this.environment = testScript.getTestEnvironment();
      GCHelper.getGCHelper().addRefWatch(this);
   }

   /**
    * Called by baseDoTestCase(). This is implemented by the tester's in each test case in the test
    * script.
    *
    * @param environment The Test environment.
    * @param logger
    * @throws InterruptedException
    */
   public abstract void doTestCase(ITestEnvironmentAccessor environment, ITestLogger logger) throws InterruptedException;

   public Element getTastCaseNumberXml(Document doc) {
      return Jaxp.createElement(doc, "Number", String.valueOf(number));
   }

   public void writeTestCaseNumber(XMLStreamWriter writer) throws XMLStreamException {
      XMLStreamWriterUtil.writeElement(writer, "Number", String.valueOf(number));
   }

   public void writeTestCaseClassName(XMLStreamWriter writer) throws XMLStreamException {
      String name = this.getClass().getName();
      if (name == null || name.length() == 0) {
         name = "";
      }
      XMLStreamWriterUtil.writeElement(writer, "Name", name);
   }

   @JsonProperty
   public String getName() {
      return this.getClass().getName();
   }

   public void writeTracability(XMLStreamWriter writer) throws XMLStreamException {
      writer.writeStartElement("Tracability");
      for (RequirementRecord record : traceability) {
         record.toXml(writer);
      }
      writer.writeEndElement();
   }

   public Element getTestCaseClassName(Document doc) {
      String name = this.getClass().getName();
      if (name == null || name.length() == 0) {
         name = "";
      }
      return Jaxp.createElement(doc, "Name", name);
   }

   public String getTestCaseClassName() {
      return this.getClass().getName();
   }

   public TestCase getTestCase() {
      return this;
   }

   /**
    * @return Returns the testCaseNumber.
    */
   public int getTestCaseNumber() {
      return number;
   }

   public ITestEnvironmentAccessor getTestEnvironment() {
      return environment;
   }

   public TestRecord getTestRecord() {
      return new TestCaseRecord(getTestEnvironment(), this);
   }

   /**
    * @return Returns the testScript.
    */
   @Override
   public TestScript getTestScript() {
      return testScript.get();
   }

   public Element getTracabilityXml(Document doc) {
      Element traceElement = doc.createElement("Tracability");
      for (RequirementRecord record : traceability) {
         traceElement.appendChild(record.toXml(doc));

      }
      return traceElement;
   }

   /**
    * @return Returns the standAlone.
    */
   public boolean isStandAlone() {
      return standAlone;
   }

   public void prompt() {
      getTestScript().prompt();
   }

   public void prompt(String message) {
      getTestScript().prompt(new TestPrompt(message, PromptResponseType.NONE));
   }

   public void promptPassFail(String message) {
      getTestScript().getLogger().methodCalled(getTestScript().getTestEnvironment(),
         new MethodFormatter().add(message));

      getTestScript().promptPassFail(message);

      getTestScript().getLogger().methodEnded(getTestScript().getTestEnvironment());
   }

   public void promptPause(String message) {
      getTestScript().promptPause(message);
   }

   public void promptStep(String message) {
      getTestScript().prompt(new TestPrompt(message, PromptResponseType.SCRIPT_STEP));
   }

   public String promptInput(String message) {
      return getTestScript().prompt(new TestPrompt(message, PromptResponseType.USER_INPUT));
   }

   /**
    * Logs the results of a test point.
    *
    * @param passed boolean T/F
    * @param expected The expected information
    * @param actual The actual information
    */
   public void testpoint(boolean passed, String testPointName, String expected, String actual) {
      logger.testpoint(this.getTestEnvironment(), this.getTestScript(), this, passed, testPointName, expected, actual);
   }

   @Override
   public String toString() {
      String description = getTestScript().getClass().getName() + "Test Case " + number + ":";
      if (traceability != null) {
         for (RequirementRecord record : traceability) {
            description += "\n\t" + record;
         }
      }
      return description;
   }

   @Override
   public Element toXml(Document doc) {
      Element testCaseElement = doc.createElement("TestCase");
      testCaseElement.appendChild(getTastCaseNumberXml(doc));
      testCaseElement.appendChild(getTestCaseClassName(doc));
      testCaseElement.appendChild(getTracabilityXml(doc));
      return testCaseElement;
   }

   @Override
   public void toXml(XMLStreamWriter writer) throws XMLStreamException {
      writer.writeStartElement("TestCase");
      writeTestCaseNumber(writer);
      writeTestCaseClassName(writer);
      writeTracability(writer);
   }

   /**
    * Starts running the test case. Calls doTestCase(), which is implemented by the tester in each test case.
    *
    * @param environment The Test Enviornment.
    */
   public void baseDoTestCase(ITestEnvironmentAccessor environment) {
      this.logger = environment.getLogger();

      logger.testCaseBegan(this); // This is required for valid outfile.
      //This creates the test case outfile logging.

      environment.getTestScript().setTestCase(this);
      OseeLog.logf(TestEnvironment.class, OteLevel.TEST_EVENT, "Starting Test Case %s.%s",
         this.getTestScript().getClass().getSimpleName(), this.getClass().getSimpleName());
      try {
         doTestCase(environment, environment.getLogger());
      } catch (InterruptedException e) {
         OseeCoreException.wrapAndThrow(e);
      }
   }

   @Override
   public void abortTestScript() {
      environment.abortTestScript();
   }

   @Override
   public boolean addTask(EnvironmentTask task) {
      return environment.addTask(task);
   }

   @Override
   public void associateObject(Class<?> c, Object obj) {
      environment.associateObject(c, obj);
   }

   @Override
   public Object getAssociatedObject(Class<?> c) {
      return environment.getAssociatedObject(c);
   }

   @Override
   public Set<Class<?>> getAssociatedObjects() {
      return environment.getAssociatedObjects();
   }

   /*
    * public ITestEnvironmentCommandCallback getClientCallback() { return environment.getClientCallback(); }
    */

   // public EnvironmentType getEnvironmentType() {
   // return environment.getEnvironmentType();
   // }
   @Override
   public long getEnvTime() {
      return environment.getEnvTime();
   }

   @Override
   public IExecutionUnitManagement getExecutionUnitManagement() {
      return environment.getExecutionUnitManagement();
   }

   @Override
   public ITestLogger getLogger() {
      return environment.getLogger();
   }

   @Override
   public IScriptControl getScriptCtrl() {
      return environment.getScriptCtrl();
   }

   /*
    * public StatusBoard getStatusBoard() { return environment.getStatusBoard(); }
    */

   @Override
   public ITestStation getTestStation() {
      return environment.getTestStation();
   }

   @Override
   public ITimerControl getTimerCtrl() {
      return environment.getTimerCtrl();
   }

   @Override
   public void onScriptComplete() throws InterruptedException {
      environment.onScriptComplete();
   }

   @Override
   public void onScriptSetup() {
      environment.onScriptSetup();
   }

   @Override
   public ICancelTimer setTimerFor(ITimeout listener, int time) {
      return environment.setTimerFor(listener, time);
   }

   public void logTestPoint(boolean isPassed, String testPointName, String expected, String actual) {
      this.getLogger().testpoint(this.getTestEnvironment(), this.getTestScript(), this, isPassed, testPointName,
         expected, actual);
   }

   public void setPurpose(String purpose) {
      testDescription.setPurpose(purpose);
   }

   public void setPreCondition(String preCondition) {
      testDescription.setPreCondition(preCondition);
   }

   public void setPostCondition(String postCondition) {
      testDescription.setPostCondition(postCondition);
   }

   public List<RequirementRecord> getScriptReqRecordTraceability() {
      return traceability;
   }

   public void addTraceability(String description) {
      this.traceability.add(new RequirementRecord(this.getTestEnvironment(), description));
   }

   public void writeToConsole(String message) {
      TestPrompt p = new TestPrompt(message);

      try {
         testScript.get().prompt(p);
      } catch (Throwable e) {
         OseeLog.log(TestEnvironment.class, Level.INFO, e.getMessage(), e);
      }
   }

   public void setTestScript(TestScript script) {
      throw new IllegalStateException("Why are you calling this one?!?!?!?");
   }

   @JsonProperty
   public List<RequirementRecord> getTraceability() {
      if (traceability.isEmpty()) {
         return null;
      } else {
         return traceability;
      }
   }
}