/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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);
            }
        }
    }
}
