/*******************************************************************************
 * 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.internal.performance;

import java.io.PrintStream;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.test.internal.performance.data.DataPoint;
import org.eclipse.test.internal.performance.data.Dim;
import org.eclipse.test.internal.performance.data.Sample;
import org.eclipse.test.internal.performance.db.DB;
import org.eclipse.test.internal.performance.db.Variations;
import org.eclipse.test.internal.performance.eval.StatisticsSession;
import org.eclipse.test.internal.performance.eval.StatisticsUtil;
import org.eclipse.test.internal.performance.eval.StatisticsUtil.Percentile;
import org.eclipse.test.performance.Dimension;
import org.eclipse.test.performance.PerformanceMeter;

public abstract class InternalPerformanceMeter extends PerformanceMeter {

    private static class DimensionComparator implements Comparator<Dim> {

        @Override
        public int compare(Dim o1, Dim o2) {
            return o1.getId() - o2.getId();
        }

    }

    public static final int       AVERAGE                            = -3;
    public static final int       SIZE                               = -4;
    public static final int       STDEV                              = -5;
    public static final int       BEFORE                             = 0;
    public static final int       AFTER                              = 1;

    protected static final String VERBOSE_PERFORMANCE_METER_PROPERTY = "InternalPrintPerformanceResults"; //$NON-NLS-1$

    private String                fScenarioId;

    private String                fShortName;
    private Dimension[]           fSummaryDimensions;
    private boolean               fSummaryIsGlobal;
    private int                   fCommentType;
    private String                fComment;

    public InternalPerformanceMeter(String scenarioId) {
        fScenarioId = scenarioId;
    }

    @Override
    public void dispose() {
        fScenarioId = null;
    }

    public abstract Sample getSample();

    /**
     * Answer the scenario ID.
     * 
     * @return the scenario ID
     */
    public String getScenarioName() {
        return fScenarioId;
    }

    @Override
    public void commit() {
        Sample sample = getSample();
        if (sample != null) {
            if (fSummaryDimensions != null) {
                sample.tagAsSummary(fSummaryIsGlobal, fShortName, fSummaryDimensions, fCommentType, fComment);
            } else if (this.fComment != null) {
                sample.setComment(this.fCommentType, this.fComment);
            }
            Variations variations = PerformanceTestPlugin.getVariations();
            if (variations != null)
                DB.store(variations, sample);
            if (!DB.isActive() || System.getProperty(VERBOSE_PERFORMANCE_METER_PROPERTY) != null) {
                printSample(System.out, sample);
                // printSampleCSV(System.out, sample);
            }
        }
    }

    private void printSample(PrintStream ps, Sample sample) {
        ps.print("Scenario '" + getScenarioName() + "' "); //$NON-NLS-1$ //$NON-NLS-2$
        DataPoint[] dataPoints = sample.getDataPoints();
        if (dataPoints.length > 0) {
            StatisticsSession s = new StatisticsSession(dataPoints);
            Dim[] dimensions = dataPoints[0].getDimensions();
            Arrays.sort(dimensions, new DimensionComparator());
            if (dimensions.length > 0) {
                List<Dim> badDimensions = new ArrayList<>();
                long n = s.getCount(dimensions[0]);
                MessageFormat format = new MessageFormat("({0,number,percent} in [{1}, {2}])"); //$NON-NLS-1$

                String spaces = "                                                                                                       "; //$NON-NLS-1$

                ps.println("(average over " + n + " samples):"); //$NON-NLS-1$ //$NON-NLS-2$
                for (Dim dimension : dimensions) {
                    double mean = s.getAverage(dimension);

                    String nameString = "  " + dimension.getName() + ":"; //$NON-NLS-1$ //$NON-NLS-2$
                    String meanString = dimension.getDisplayValue(mean);
                    int align = firstNonDigit(meanString);
                    int endIndex = 30 - align - nameString.length();
                    if (endIndex > 0)
                        meanString = spaces.substring(0, endIndex) + meanString;

                    align = nameString.length() + meanString.length();

                    Percentile percentile = StatisticsUtil.T95;
                    double[] confidenceInterval = s.getConfidenceInterval(dimension, percentile);

                    StringBuffer printBuffer;
                    if (n <= 2) {
                        printBuffer = new StringBuffer(" (no confidence)"); //$NON-NLS-1$
                    } else {
                        printBuffer = new StringBuffer();
                        int ns = align;
                        while (ns++ < 40)
                            printBuffer.append(' ');
                        printBuffer
                                .append(format.format(new Object[] { Double.valueOf(percentile.inside()),
                                        dimension.getDisplayValue(confidenceInterval[0]),
                                        dimension.getDisplayValue(confidenceInterval[1]) }));
                    }

                    align += printBuffer.length();
                    try {
                        while (align++ < 70)
                            printBuffer.append(' ');
                        printBuffer.append(checkSampleSize(s, sample, dimension));
                    }
                    catch (CoreException x) {
                        badDimensions.add(dimension);
                        continue;
                    }

                    ps.print(nameString);
                    ps.print(meanString);
                    ps.println(printBuffer);
                }

                if (!badDimensions.isEmpty()) {
                    ps.print("  Dimensions with unusable statistical properties: "); //$NON-NLS-1$
                    for (Iterator<Dim> iter = badDimensions.iterator(); iter.hasNext();) {
                        Dim dimension = iter.next();
                        ps.print(dimension.getName());
                        if (iter.hasNext())
                            ps.print(", "); //$NON-NLS-1$
                    }
                    ps.println();
                }
            }
        }
        ps.println();
    }

    private String checkSampleSize(StatisticsSession s, Sample sample, Dim dimension) throws CoreException {
        long sampleSize = s.getCount(dimension);
        double stdev = s.getStddev(dimension);
        double mean = s.getAverage(dimension);

        if (stdev == 0)
            return ""; //$NON-NLS-1$

        // measurable effect size
        // sampleSize= 16 * stdev^2 / effect^2
        double effectSize = 4 * Math.sqrt(stdev * stdev / sampleSize);

        double base;
        String baseName;
        if (stdev > Math.abs(mean)) {
            base = stdev;
            baseName = "stdev"; //$NON-NLS-1$
        } else {
            base = Math.abs(mean);
            baseName = "mean"; //$NON-NLS-1$
        }
        double fivePercentEffect = 0.05 * base;
        long requiredSampleSizeForFivePercentEffect = Math.round(16 * stdev * stdev / fivePercentEffect / fivePercentEffect + 0.5);

        // if (requiredSampleSizeForFivePercentEffect > 1000 || Double.isNaN(stdev))
        //			throw new CoreException(new Status(IStatus.OK, "org.eclipse.text.performance", IStatus.OK, "no message", null)); //$NON-NLS-1$ //$NON-NLS-2$

        NumberFormat numberInstance = NumberFormat.getNumberInstance();
        numberInstance.setMaximumFractionDigits(1);
        numberInstance.setMinimumFractionDigits(1);

        String measurableMsg = " Measurable effect: " + dimension.getDisplayValue(effectSize) + " (" + numberInstance.format(effectSize / stdev) + " SDs)"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        if (fivePercentEffect < effectSize)
            measurableMsg += " (required sample size for an effect of 5% of " + baseName + ": " + requiredSampleSizeForFivePercentEffect + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

        return measurableMsg;
    }

    private int firstNonDigit(String string) {
        int length = string.length();
        for (int i = 0; i < length; i++)
            if (!Character.isDigit(string.charAt(i)) && string.charAt(i) != '-' && string.charAt(i) != '.')
                return i;
        return length;
    }

    void printSampleCSV(PrintStream ps, Sample sample) {
        final char SEPARATOR = '\t';
        DataPoint[] dataPoints = sample.getDataPoints();
        if (dataPoints.length > 0) {
            Dim[] dimensions = dataPoints[0].getDimensions();
            Arrays.sort(dimensions, new DimensionComparator());
            if (dimensions.length > 0) {
                /* print dimensions */
                for (Dim dimension : dimensions) {
                    ps.print(dimension.getName());
                    ps.print(SEPARATOR);
                }
                ps.println("scenario"); //$NON-NLS-1$

                for (int p = 0; p < dataPoints.length - 1; p += 2) {
                    DataPoint before = dataPoints[p];
                    DataPoint after = dataPoints[p + 1];
                    for (Dim dimension : dimensions) {
                        long valBefore = before.getScalar(dimension).getMagnitude();
                        long valAfter = after.getScalar(dimension).getMagnitude();
                        ps.print(valAfter - valBefore);
                        ps.print(SEPARATOR);
                    }
                    ps.print(sample.getShortname() != null ? sample.getShortname() : sample.getScenarioID());
                    ps.println();
                }

                ps.println();
            }
        }
    }

    public void tagAsSummary(boolean global, String shortName, Dimension[] dims) {
        fSummaryIsGlobal = global;
        fShortName = shortName;
        fSummaryDimensions = dims;
    }

    public void setComment(int commentType, String comment) {
        fCommentType = commentType;
        fComment = comment;
    }
}
