/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.test.performance;

import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.Platform;
import org.eclipse.test.internal.performance.InternalDimensions;
import org.eclipse.test.internal.performance.InternalPerformanceMeter;
import org.eclipse.test.internal.performance.NullPerformanceMeter;
import org.eclipse.test.internal.performance.OSPerformanceMeterFactory;
import org.eclipse.test.internal.performance.PerformanceMeterFactory;
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
import org.eclipse.test.internal.performance.data.Dim;
import org.eclipse.test.internal.performance.eval.AbsoluteBandChecker;
import org.eclipse.test.internal.performance.eval.AssertChecker;
import org.eclipse.test.internal.performance.eval.Evaluator;
import org.eclipse.test.internal.performance.eval.IEvaluator;
import org.eclipse.test.internal.performance.eval.RelativeBandChecker;
import org.osgi.framework.Bundle;

import junit.framework.TestCase;

/**
 * Helper for performance measurements. Currently provides performance meter creation and checking of measurements.
 *
 * This class is not intended to be subclassed by clients.
 *
 * @since 3.1
 */
public class Performance {

    /**
     * A comment kind of a comment that explains a performance degradation.
     */
    public static final int         EXPLAINS_DEGRADATION_COMMENT       = 1;

    private static final String     PERFORMANCE_METER_FACTORY          = "/option/performanceMeterFactory"; //$NON-NLS-1$
    private static final String     PERFORMANCE_METER_FACTORY_PROPERTY = "PerformanceMeterFactory";        //$NON-NLS-1$

    private static Performance      fgDefault;

    private PerformanceMeterFactory fPerformanceMeterFactory;
    private IEvaluator              fDefaultEvaluator;

    /** Null performance meter singleton */
    private NullPerformanceMeter    fNullPeformanceMeter;

    /**
     * Private constructor to block instance creation.
     */
    private Performance() {
        // empty
    }

    /**
     * Returns the singleton of <code>Performance</code>
     *
     * @return the singleton of <code>Performance</code>
     */
    public static Performance getDefault() {
        if (fgDefault == null)
            fgDefault = new Performance();
        return fgDefault;
    }

    /**
     * Asserts default properties of the measurements captured by the given performance meter.
     *
     * @param performanceMeter
     *            the performance meter
     * @throws RuntimeException
     *             if the properties do not hold
     */
    public void assertPerformance(PerformanceMeter performanceMeter) {
        if (fDefaultEvaluator == null) {
            fDefaultEvaluator = new Evaluator();
            fDefaultEvaluator.setAssertCheckers(new AssertChecker[] { new RelativeBandChecker(InternalDimensions.ELAPSED_PROCESS,
                    0.0f, 1.10f),
            // new RelativeBandChecker(InternalDimensions.CPU_TIME, 0.0f, 1.10f),
            // new RelativeBandChecker(InternalDimensions.WORKING_SET, 0.0f, 3.00f),
            // new RelativeBandChecker(InternalDimensions.USED_JAVA_HEAP, 0.0f, 2.00f),
            // new RelativeBandChecker(InternalDimensions.SYSTEM_TIME, 0.0f, 1.10f)
                    });
        }
        fDefaultEvaluator.evaluate(performanceMeter);
    }

    /**
     * Asserts that the measurement specified by the dimension captured in the given performance meter is within a certain range
     * with respect to some reference value. If the performance meter doesn't provide the specified dimension, the call has no
     * effect.
     *
     * @param performanceMeter
     *            the performance meter
     * @param dim
     *            the Dimension to check
     * @param lowerPercentage
     *            a negative number indicating the percentage the measured value is allowed to be smaller than some reference value
     * @param upperPercentage
     *            a positive number indicating the percentage the measured value is allowed to be greater than some reference value
     * @throws RuntimeException
     *             if the properties do not hold
     */
    public void assertPerformanceInRelativeBand(PerformanceMeter performanceMeter, Dimension dim, int lowerPercentage,
            int upperPercentage) {
        Evaluator e = new Evaluator();
        e.setAssertCheckers(new AssertChecker[] { new RelativeBandChecker((Dim) dim, 1.0 + (lowerPercentage / 100.0),
                1.0 + (upperPercentage / 100.0)), });
        e.evaluate(performanceMeter);
    }

    /**
     * Asserts that the measurement specified by the dimension captured in the given performance meter is within a certain range
     * with respect to some reference value. If the performance meter doesn't provide the specified dimension, the call has no
     * effect.
     *
     * @param performanceMeter
     *            the performance meter
     * @param dim
     *            the Dimension to check
     * @param lowerBand
     *            a negative number indicating the absolute amount the measured value is allowed to be smaller than some reference
     *            value
     * @param upperBand
     *            a positive number indicating the absolute amount the measured value is allowed to be greater than some reference
     *            value
     * @throws RuntimeException
     *             if the properties do not hold
     */
    public void assertPerformanceInAbsoluteBand(PerformanceMeter performanceMeter, Dimension dim, int lowerBand, int upperBand) {
        Evaluator e = new Evaluator();
        e.setAssertCheckers(new AssertChecker[] { new AbsoluteBandChecker((Dim) dim, lowerBand, upperBand), });
        e.evaluate(performanceMeter);
    }

    /**
     * Creates a performance meter for the given scenario id.
     *
     * @param scenarioId
     *            the scenario id
     * @return a performance meter for the given scenario id
     * @throws IllegalArgumentException
     *             if a performance meter for the given scenario id has already been created
     */
    public PerformanceMeter createPerformanceMeter(String scenarioId) {
        return getPeformanceMeterFactory().createPerformanceMeter(scenarioId);
    }

    /**
     * Returns the null performance meter singleton.
     *
     * @return the null performance meter singleton
     */
    public PerformanceMeter getNullPerformanceMeter() {
        if (fNullPeformanceMeter == null)
            fNullPeformanceMeter = new NullPerformanceMeter();
        return fNullPeformanceMeter;
    }

    /**
     * Returns a default scenario id for the given test. The test's name must have been set, such that <code>test.getName()</code>
     * is not <code>null</code>.
     *
     * @param test
     *            the test
     * @return the default scenario id for the test
     */
    public String getDefaultScenarioId(TestCase test) {
        return test.getClass().getName() + '#' + test.getName() + "()"; //$NON-NLS-1$
    }

    /**
     * Returns a default scenario id for the given test and id. The test's name must have been set, such that
     * <code>test.getName()</code> is not <code>null</code>. The id distinguishes multiple scenarios in the same test.
     *
     * @param test
     *            the test
     * @param id
     *            the id
     * @return the default scenario id for the test and the id
     */
    public String getDefaultScenarioId(TestCase test, String id) {
        return getDefaultScenarioId(test) + '-' + id;
    }

    private PerformanceMeterFactory getPeformanceMeterFactory() {
        if (fPerformanceMeterFactory == null)
            fPerformanceMeterFactory = createPerformanceMeterFactory();
        return fPerformanceMeterFactory;
    }

    private PerformanceMeterFactory createPerformanceMeterFactory() {
        PerformanceMeterFactory factory;
        factory = tryInstantiate(System.getProperty(PERFORMANCE_METER_FACTORY_PROPERTY));
        if (factory != null)
            return factory;

        factory = tryInstantiate(Platform.getDebugOption(PerformanceTestPlugin.PLUGIN_ID + PERFORMANCE_METER_FACTORY));
        if (factory != null)
            return factory;

        return createDefaultPerformanceMeterFactory();
    }

    private PerformanceMeterFactory tryInstantiate(String className) {
        PerformanceMeterFactory instance = null;
        if (className != null && className.length() > 0) {
            try {
                Class<?> c = null;
                if (Platform.isRunning()) {
                    int separator = className.indexOf(':');
                    Bundle bundle = null;
                    if (separator == -1) {
                        bundle = PerformanceTestPlugin.getDefault().getBundle();
                    } else {
                        String bundleName = className.substring(0, separator);
                        className = className.substring(separator + 1);
                        bundle = Platform.getBundle(bundleName);
                    }
                    c = bundle.loadClass(className);
                } else {
                    c = Class.forName(className);
                }
                instance = (PerformanceMeterFactory) c.getDeclaredConstructor().newInstance();
            } catch (
                    ClassNotFoundException |
                    InstantiationException |
                    IllegalAccessException |
                    ClassCastException |
                    IllegalArgumentException |
                    InvocationTargetException |
                    NoSuchMethodException |
                    SecurityException e) {
                PerformanceTestPlugin.log(e);
            }
        }
        return instance;
    }

    private PerformanceMeterFactory createDefaultPerformanceMeterFactory() {
        return new OSPerformanceMeterFactory();
    }

    /**
     * Mark the scenario represented by the given PerformanceMeter to be included into the global and the component performance
     * summary. The summary shows the given dimension of the scenario and labels the scenario with the short name.
     *
     * @param pm
     *            the PerformanceMeter
     * @param shortName
     *            a short (shorter than 40 characters) descriptive name of the scenario
     * @param dimension
     *            the dimension to show in the summary
     */
    public void tagAsGlobalSummary(PerformanceMeter pm, String shortName, Dimension dimension) {
        tagAsGlobalSummary(pm, shortName, new Dimension[] { dimension });
    }

    /**
     * Mark the scenario represented by the given PerformanceMeter to be included into the global and the component performance
     * summary. The summary shows the given dimensions of the scenario and labels the scenario with the short name.
     *
     * @param pm
     *            the PerformanceMeter
     * @param shortName
     *            a short (shorter than 40 characters) descriptive name of the scenario
     * @param dimensions
     *            an array of dimensions to show in the summary
     */
    public void tagAsGlobalSummary(PerformanceMeter pm, String shortName, Dimension[] dimensions) {
        if (pm instanceof InternalPerformanceMeter) {
            InternalPerformanceMeter ipm = (InternalPerformanceMeter) pm;
            ipm.tagAsSummary(true, shortName, dimensions);
        }
    }

    /**
     * Mark the scenario represented by the given PerformanceMeter to be included into the component performance summary. The
     * summary shows the given dimension of the scenario and labels the scenario with the short name.
     *
     * @param pm
     *            the PerformanceMeter
     * @param shortName
     *            a short (shorter than 40 characters) descriptive name of the scenario
     * @param dimension
     *            the dimension to show in the summary
     */
    public void tagAsSummary(PerformanceMeter pm, String shortName, Dimension dimension) {
        tagAsSummary(pm, shortName, new Dimension[] { dimension });
    }

    /**
     * Mark the scenario represented by the given PerformanceMeter to be included into the component performance summary. The
     * summary shows the given dimensions of the scenario and labels the scenario with the short name.
     *
     * @param pm
     *            the PerformanceMeter
     * @param shortName
     *            a short (shorter than 40 characters) descriptive name of the scenario
     * @param dimensions
     *            an array of dimensions to show in the summary
     */
    public void tagAsSummary(PerformanceMeter pm, String shortName, Dimension[] dimensions) {
        if (pm instanceof InternalPerformanceMeter) {
            InternalPerformanceMeter ipm = (InternalPerformanceMeter) pm;
            ipm.tagAsSummary(false, shortName, dimensions);
        }
    }

    /**
     * Set a comment for the scenario represented by the given PerformanceMeter. Currently only comments with a commentKind of
     * EXPLAINS_DEGRADATION_COMMENT are used. Their commentText is shown in a hover of the performance summaries graph if a
     * performance degradation exists.
     *
     * @param pm
     *            the PerformanceMeter
     * @param commentKind
     *            kind of comment. Must be EXPLAINS_DEGRADATION_COMMENT to have an effect.
     * @param commentText
     *            the comment (shorter than 400 characters)
     */
    public void setComment(PerformanceMeter pm, int commentKind, String commentText) {
        if (commentKind == EXPLAINS_DEGRADATION_COMMENT) {
            if (pm instanceof InternalPerformanceMeter) {
                InternalPerformanceMeter ipm = (InternalPerformanceMeter) pm;
                ipm.setComment(commentKind, commentText);
            }
        }
    }
}
