/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.framework;

import java.io.*;
import java.math.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.indirection.*;

/**
 * <p><b>Purpose</b>:Class stores the test exception if raised and decides whether the test was
 * successfull or not.
 */
public class TestResult implements ResultInterface, Comparable, Serializable {
    public static final String ERROR = "Error";
    public static final String FATAL_ERROR = "FatalError";
    public static final String PASSED = "Passed";
    public static final String PROBLEM = "Problem";
    public static final String WARNING = "Warning";
    protected String name;
    protected String description;
    protected BigDecimal id;
    protected String outcome;
    protected transient ValueHolderInterface summary;
    protected transient ValueHolderInterface loadBuildSummary;
    protected EclipseLinkException exception;
    protected transient TestCase testCase;
    protected long totalTime;
    protected long testTime;

    public TestResult() {
        summary = new ValueHolder();
        loadBuildSummary = new ValueHolder();
    }

    public TestResult(TestCase testCase) {
        this.outcome = "Passed";
        this.testCase = testCase;
        try {
            this.name = testCase.getName();
            this.description = testCase.getDescription();
        } catch (NullPointerException e) {
        }
        summary = new ValueHolder();
        loadBuildSummary = new ValueHolder();
    }

    public TestResult(TestCase testCase, String result) {
        this.outcome = result;
        this.testCase = testCase;
        this.name = testCase.getName();
        this.description = testCase.getDescription();
        summary = new ValueHolder();
        loadBuildSummary = new ValueHolder();
    }

    @Override
    public int compareTo(Object summary) {
        return getName().compareTo(((TestResult)summary).getName());
    }

    public String getDescription() {
        return description;
    }

    public EclipseLinkException getException() {
        return exception;
    }

    @Override
    public boolean shouldLogResult() {
        return !hasPassed();
    }

    /**
     * Not return warning stacktrace
     */
    public String getExceptionStackTraceForDatabase() {
        if ((exception != null) && !hasWarning()) {
            StringWriter writer = new StringWriter();
            exception.printStackTrace(new PrintWriter(writer));
            String trace = writer.toString();

            // Trim to 2000
            // Must trim for writing to the database.
            if (trace.length() >= 2000) {
                trace = trace.substring(0, 1995);
            }
            return trace;
        }
        return null;
    }

    /**
     * Not return warning stacktrace
     */
    public String getExceptionStackTrace() {
        if (exception != null) {
            StringWriter writer = new StringWriter();
            exception.printStackTrace(new PrintWriter(writer));
            String trace = writer.toString();
            return trace;
        }
        return null;
    }

    public BigDecimal getId() {
        return id;
    }

    public long getTestTime() {
        return testTime;
    }

    public long getTotalTime() {
        return totalTime;
    }

    public void setTestTime(long testTime) {
        this.testTime = testTime;
    }

    public void setTotalTime(long totalTime) {
        this.totalTime = totalTime;
    }

    /**
     * This is use to return null when the test no error but warning
     */
    public EclipseLinkException getLoadBuildException() {
        return exception;
    }

    public LoadBuildSummary getLoadBuildSummary() {
        return (LoadBuildSummary)loadBuildSummary.getValue();
    }

    public ValueHolderInterface getLoadBuildSummaryHolder() {
        return loadBuildSummary;
    }

    public String getName() {
        return name;
    }

    /**
     * Return the outcome of the test.
     * This is one of, "Passed", "Warning", "Error", "FatalError"
     */
    public String getOutcome() {
        return outcome;
    }

    /**
     * Depending upon the result of the exception the test outcome is decided.
     */
    public String getOutcomeForException(EclipseLinkException exception) {
        if (exception == null) {
            return PASSED;
        } else if (exception instanceof TestErrorException) {
            return ERROR;
        } else if (exception instanceof TestProblemException) {
            return PROBLEM;
        } else if (exception instanceof TestWarningException) {
            return WARNING;
        } else {
            return FATAL_ERROR;
        }
    }

    public TestResultsSummary getSummary() {
        return (TestResultsSummary)summary.getValue();
    }

    public ValueHolderInterface getSummaryHolder() {
        return summary;
    }

    public TestCase getTestCase() {
        return testCase;
    }

    public void setTestCase(TestCase testCase) {
        this.testCase = testCase;
    }

    /**
     * A error means that the verify detected a failure in the test.
     */
    public boolean hasError() {
        return getOutcome().equals(ERROR);
    }

    /**
     * A fatal error means that an unhandled exception occurred during the test.
     */
    public boolean hasFatalError() {
        return getOutcome().equals(FATAL_ERROR);
    }

    /**
     * Passed means the test was ok.
     */
    @Override
    public boolean hasPassed() {
        return getOutcome().equals(PASSED);
    }

    /**
     * A problem means a error occurred during setup or reset.
     */
    public boolean hasProblem() {
        return getOutcome().equals(PROBLEM);
    }

    /**
     * A warning means the test did not pass, but there may be a reason for it too fail on this platform.
     */
    public boolean hasWarning() {
        return getOutcome().equals(WARNING);
    }

    /**
     * Return if the test failed (did not pass or throw warning).
     */
    public boolean hasFailed() {
        return !(hasPassed() || hasWarning());
    }

    /**
     * logs the result of the test on the print stream.
     */
    public void logRegressionResult(Writer log) {
        String indentationString = getTestCase().getIndentationString();
        try {
            log.write(indentationString + "RESULT:      " + getOutcome() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.flush();
        } catch (IOException exception) {
        }
        LoadBuildSystem.loadBuild.addResult(this);
    }

    /**
     * logs the result of the test on the print stream.
     */
    @Override
    public void logResult(Writer log) {
        String indentationString = getTestCase().getIndentationString();
        try {
            if (hasError() || hasFatalError() || hasProblem()) {
                log.write(indentationString + "##FAILURE##" + org.eclipse.persistence.internal.helper.Helper.cr());
            }
            log.write(indentationString + "TEST TIME:      " + getTestTime() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.write(indentationString + "TOTAL TIME:      " + getTotalTime() + org.eclipse.persistence.internal.helper.Helper.cr());
            log.write(indentationString + "RESULT:      " + getOutcome() + org.eclipse.persistence.internal.helper.Helper.cr());
            if (getException() != null) {
                getException().setIndentationString(indentationString);
                // Do not print the stack for warnings, just the exception.
                if (hasWarning()) {
                    log.write(getException() + org.eclipse.persistence.internal.helper.Helper.cr());
                } else {
                    log.write(indentationString);
                    log.flush();
                    log.write(getExceptionStackTrace() + org.eclipse.persistence.internal.helper.Helper.cr());
                }
            }
            log.flush();
        } catch (IOException exception) {
        }
        LoadBuildSystem.loadBuild.addResult(this);
    }

    public void setDescription(String aDescription) {
        description = aDescription;
    }

    /**
     * Set the exception raised by the test case in the result.
     * Set the outcome dependant on the exeception.
     */
    public void setException(EclipseLinkException anException) {
        exception = anException;
        setOutcome(getOutcomeForException(anException));
    }

    /**
     * Return the exception raised by the test.
     */
    public void setExceptionStackTrace(String stackTrace) {
        if (stackTrace != null) {
            if (exception == null) {
                exception = new TestException(stackTrace);
            }
        }
    }

    public void setId(BigDecimal anId) {
        id = anId;
    }

    public void setLoadBuildSummary(LoadBuildSummary summary) {
        if (loadBuildSummary == null) {
            loadBuildSummary = new ValueHolder();
        }
        loadBuildSummary.setValue(summary);
    }

    public void setLoadBuildSummaryHolder(ValueHolderInterface holder) {
        loadBuildSummary = holder;
    }

    public void setName(String aName) {
        name = aName;
    }

    /**
     * Set the outcome of the test.
     * This is one of, "Passed", "Warning", "Error", "FatalError"
     */
    public void setOutcome(String outcome) {
        this.outcome = outcome;
    }

    public void setSummary(TestResultsSummary summary) {
        if (this.summary == null) {
            this.summary = new ValueHolder();
        }
        this.summary.setValue(summary);
    }

    public void setSummaryHolder(ValueHolderInterface holder) {
        summary = holder;
    }

    public void setupTestResult(TestCase testCase) {
        this.testCase = testCase;
    }
}
