/**
 * Copyright (c) 2014 Codetrails GmbH.
 * 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:
 *    Daniel Haftstein - initial tests.
 */
package org.eclipse.epp.logging.aeri.core.util;

import static org.eclipse.emf.ecore.util.EcoreUtil.getAllContents;
import static org.eclipse.epp.logging.aeri.core.util.Reports.newStatus;
import static org.eclipse.epp.logging.aeri.tests.util.TestReports.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.epp.logging.aeri.core.IModelFactory;
import org.eclipse.epp.logging.aeri.core.IReport;
import org.eclipse.epp.logging.aeri.core.IStackTraceElement;
import org.eclipse.epp.logging.aeri.core.ISystemSettings;
import org.eclipse.epp.logging.aeri.core.IThrowable;
import org.eclipse.epp.logging.aeri.tests.util.TestReports;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class ReportsTest {
    IModelFactory eFac = IModelFactory.eINSTANCE;
    private static final List<Pattern> PREFIX_WHITELIST = WildcardPatterns
            .convert(Arrays.asList("sun.*", "java.*", "javax.*", "org.eclipse.*"));

    private static final String WHITELISTED_CLASSNAME = "java.lang.RuntimeException";
    private static final String NOT_WHITELISTED_CLASSNAME = "foo.bar.FooBarException";

    private static final String WHITELISTED_CLASSNAME_2 = "java.lang.String";
    private static final String WHITELISTED_METHODNAME_2 = "trim";

    private static final String NOT_WHITELISTED_CLASSNAME_2 = "foo.bar.AnyClass";
    private static final String NOT_WHITELISTED_METHODNAME_2 = "foo";

    private static String ANONYMIZED_TAG = "HIDDEN";

    private ISystemSettings settings;

    @Before
    public void before() {
        settings = eFac.createSystemSettings();
        exCounter = 1;
        stCounter = 1;
    }

    @Test
    public void testClearEventMessage() {
        IReport report = createTestReport();
        Reports.anonymizeMessages(report);
        assertThat(report.getStatus().getMessage(), is(ANONYMIZED_TAG));
    }

    @Test
    public void testDeclaringClassToNull()
            throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
        java.lang.Throwable some = new java.lang.Throwable("contains null");
        java.lang.StackTraceElement ste = new java.lang.StackTraceElement("class", "method", null, 1);
        Field field = java.lang.StackTraceElement.class.getDeclaredField("declaringClass");
        field.setAccessible(true);
        field.set(ste, null);
        some.setStackTrace(new java.lang.StackTraceElement[] { ste });
        IThrowable sut = Reports.newThrowable(some);
        Assert.assertEquals("MISSING", sut.getStackTrace().get(0).getClassName());
    }

    @Test
    public void testClearThrowableMessage() {
        IReport event = createTestReport();
        Reports.anonymizeMessages(event);
        assertThat(event.getStatus().getException().getMessage(), is(ANONYMIZED_TAG));
    }

    @Test
    public void testAnonymizeThrowableDtoClassname() {
        IThrowable throwable = createThrowable(NOT_WHITELISTED_CLASSNAME);
        Reports.anonymizeStackTraces(throwable, PREFIX_WHITELIST);
        assertThat(throwable.getClassName(), is(ANONYMIZED_TAG));
    }

    @Test
    public void testAnonymizeThrowableDtoWhitelistedClassname() {
        IThrowable throwable = createThrowable(WHITELISTED_CLASSNAME);
        Reports.anonymizeStackTraces(throwable, PREFIX_WHITELIST);
        assertThat(throwable.getClassName(), is(WHITELISTED_CLASSNAME));
    }

    @Test
    public void testAnonymizeIStackTraceElementDtoClassnames() {
        IStackTraceElement element = createStackTraceElement(NOT_WHITELISTED_CLASSNAME_2, NOT_WHITELISTED_METHODNAME_2);
        Reports.anonymizeStackTraceElements(element, PREFIX_WHITELIST);
        assertThat(element.getClassName(), is(ANONYMIZED_TAG));
    }

    @Test
    public void testAnonymizeIStackTraceElementDtoWhitelistedClassnames() {
        IStackTraceElement element = createStackTraceElement(WHITELISTED_CLASSNAME, "");
        Reports.anonymizeStackTraceElements(element, PREFIX_WHITELIST);
        assertThat(element.getClassName(), is(WHITELISTED_CLASSNAME));
    }

    @Test
    public void testAnonymizeIStackTraceElementMethodname() {
        IStackTraceElement element = createStackTraceElement(NOT_WHITELISTED_CLASSNAME_2, NOT_WHITELISTED_METHODNAME_2);
        Reports.anonymizeStackTraceElements(element, PREFIX_WHITELIST);
        assertThat(element.getMethodName(), is(ANONYMIZED_TAG));
    }

    @Test
    public void testAnonymizeIStackTraceElementWhitelistedMethodname() {
        IStackTraceElement element = createStackTraceElement(WHITELISTED_CLASSNAME_2, WHITELISTED_METHODNAME_2);
        Reports.anonymizeStackTraceElements(element, PREFIX_WHITELIST);
        assertThat(element.getMethodName(), is(WHITELISTED_METHODNAME_2));
    }

    @Test
    public void testFingerprint() {

        Exception cause = new RuntimeException("cause");
        Exception r1 = new RuntimeException("exception message");

        r1.fillInStackTrace();
        Exception r2 = new RuntimeException("exception message", cause);
        r2.fillInStackTrace();

        IStatus s1 = new Status(IStatus.ERROR, "org.eclipse.epp.logging.aeri", "some error message", r1);
        IStatus s2 = new Status(IStatus.ERROR, "org.eclipse.epp.logging.aeri", "some error message", r2);

        org.eclipse.epp.logging.aeri.core.IStatus noCause = Reports.newStatus(s1);
        org.eclipse.epp.logging.aeri.core.IStatus withCause = Reports.newStatus(s2);

        Assert.assertNotEquals(noCause.getFingerprint(), withCause.getFingerprint());
    }

    @Test
    public void testFingerprintNested() {
        Exception root = new RuntimeException("root");
        IStatus s1 = new Status(IStatus.ERROR, "org.eclipse.epp.logging.aeri", "some error message", root);
        IStatus s2 = new MultiStatus("org.eclipse.epp.logging.aeri", 0, new IStatus[] { s1 }, "some error message", root);

        org.eclipse.epp.logging.aeri.core.IStatus normal = Reports.newStatus(s1);
        org.eclipse.epp.logging.aeri.core.IStatus multi = Reports.newStatus(s2);

        Assert.assertNotEquals(normal.getFingerprint(), multi.getFingerprint());
    }

    @Test
    public void testCoreExceptionHandling() {
        IStatus causingStatus = new Status(IStatus.ERROR, "the.causing.plugin", "first message");
        java.lang.Throwable causingException = new CoreException(causingStatus);
        IStatus causedStatus = new Status(IStatus.WARNING, "some.calling.plugin", "any other message", causingException);
        java.lang.Throwable rootException = new CoreException(causedStatus);
        IStatus rootEvent = new Status(IStatus.ERROR, "org.eclipse.epp.logging.aeri", "someErrorMessage", rootException);

        org.eclipse.epp.logging.aeri.core.IStatus rootStatus = Reports.newStatus(rootEvent);

        org.eclipse.epp.logging.aeri.core.IStatus child = rootStatus.getChildren().get(0);
        org.eclipse.epp.logging.aeri.core.IStatus leaf = child.getChildren().get(0);
        assertThat(child.getPluginId(), is("some.calling.plugin"));
        assertThat(leaf.getPluginId(), is("the.causing.plugin"));
    }

    @Test
    public void testMultistatusDuplicateChildFiltering() {

        Exception e1 = new Exception("Stack Trace");
        e1.setStackTrace(createStacktraceForClasses("java.lang.Object", "org.eclipse.core.internal.jobs.WorkerPool",
                "org.eclipse.core.internal.jobs.WorkerPool", "org.eclipse.core.internal.jobs.Worker"));
        IStatus s1 = new Status(IStatus.ERROR, "org.eclipse.ui.monitoring",
                "Thread 'Worker-3' tid=39 (TIMED_WAITING)\n" + "Waiting for: org.eclipse.core.internal.jobs.WorkerPool@416dc7fc", e1);

        Exception e2 = new Exception("Stack Trace");
        e2.setStackTrace(TestReports.createStacktraceForClasses("java.lang.Object", "org.eclipse.core.internal.jobs.WorkerPool",
                "org.eclipse.core.internal.jobs.WorkerPool", "org.eclipse.core.internal.jobs.Worker"));
        IStatus s2 = new Status(IStatus.ERROR, "org.eclipse.ui.monitoring",
                "Thread 'Worker-2' tid=36 (TIMED_WAITING)\n" + "Waiting for: org.eclipse.core.internal.jobs.WorkerPool@416dc7fc", e2);

        IStatus multi = new MultiStatus("org.eclipse.ui.monitoring", 0, new IStatus[] { s1, s2 }, "UI freeze of 10s at 08:09:02.936",
                new RuntimeException("stand-in-stacktrace"));
        org.eclipse.epp.logging.aeri.core.IStatus newStatus = Reports.newStatus(multi);
        assertThat(newStatus.getChildren().size(), is(1));
        assertThat(newStatus.getMessage(), is("UI freeze of 10s at 08:09:02.936 [1 child-status duplicates removed by Error Reporting]"));
    }

    @Test
    public void testMultistatusChildFilteringHandlesEmptyStacktrace() {

        Exception e1 = new Exception("Stack Trace 1");
        e1.setStackTrace(new java.lang.StackTraceElement[0]);
        IStatus s1 = new Status(IStatus.ERROR, "org.eclipse.ui.monitoring", "Thread 'Signal Dispatcher' tid=4 (RUNNABLE)", e1);

        IStatus multi = new MultiStatus("org.eclipse.ui.monitoring", 0, new IStatus[] { s1 }, "UI freeze of 10s at 08:09:02.936",
                new RuntimeException("stand-in-stacktrace"));
        org.eclipse.epp.logging.aeri.core.IStatus newStatus = Reports.newStatus(multi);
        assertThat(newStatus.getChildren().size(), is(0));
    }

    @Test
    public void testMultistatus() {
        MultiStatus mst = mst(ex(), st(ex()), st(ex()), st(ex()), st(ex()), st(ex()));
        org.eclipse.epp.logging.aeri.core.IStatus res = Reports.newStatus(mst);
        assertThat(numberOfStatusObjects(res), is(6));
    }

    @Test
    public void testCausedByContainsCoreExceptionWithStatus() {
        Status st = st(ex(cex(st(ex()))));
        org.eclipse.epp.logging.aeri.core.IStatus res = newStatus(st);
        assertThat(numberOfStatusObjects(res), is(2));
    }

    @Test
    public void testCausedByContainsCoreExceptionWithMultistatus() {
        MultiStatus mst = mst(ex(), st(ex()), st(ex()), st(ex()), st(ex()), st(ex()));
        Status st = st(ex(cex(mst)));
        org.eclipse.epp.logging.aeri.core.IStatus res = Reports.newStatus(st);
        assertThat(numberOfStatusObjects(res), is(7));
    }

    @Test
    public void testDetachMultistatusFromCoreException() {
        // #input
        // st4
        // -ex4
        // --cex
        // ---mst3
        // ----ex1
        // ----st1
        // -----ex2
        // ----st2
        // -----ex3
        Status st = st(ex(cex(mst(ex(), st(ex()), st(ex())))));
        // #expected output
        // st4
        // -ex4
        // --cex(mst3)
        // ---ex1
        // -mst3 (moved from cex to st4.children)
        // --ex1
        // --st1
        // ---ex2
        // --st2
        // ---ex3
        org.eclipse.epp.logging.aeri.core.IStatus st4 = Reports.newStatus(st);
        IThrowable ex4 = st4.getException();
        IThrowable cex = ex4.getCause();
        IThrowable ex1 = cex.getCause();
        org.eclipse.epp.logging.aeri.core.IStatus mst3 = st4.getChildren().get(0);
        IThrowable ex1b = mst3.getException();
        org.eclipse.epp.logging.aeri.core.IStatus st1 = mst3.getChildren().get(0);
        IThrowable ex2 = st1.getException();
        org.eclipse.epp.logging.aeri.core.IStatus st2 = mst3.getChildren().get(1);
        IThrowable ex3 = st2.getException();

        assertThat(st4.getMessage(), is("st4"));
        assertThat(ex4.getMessage(), is("ex4"));
        assertThat(cex.getMessage(), is("mst3"));
        assertThat(ex1.getMessage(), is("ex1"));
        assertThat(mst3.getMessage(), is("mst3 [detached from CoreException of Status 'st4' by Error Reporting]"));
        assertThat(ex1b.getMessage(), is("ex1"));
        assertThat(st1.getMessage(), is("st1"));
        assertThat(ex2.getMessage(), is("ex2"));
        assertThat(st2.getMessage(), is("st2"));
        assertThat(ex3.getMessage(), is("ex3"));
    }

    @Test
    public void testDetachMultipleMultistatusFromCoreException() {
        // #input
        // st9
        // -ex6
        // --cex
        // ---st8
        // ----cex
        // -----mst7
        // ------ex1
        // ------st4
        // -------cex
        // --------mst3
        // ---------ex2
        // ---------st1
        // ----------ex3
        // ---------st2
        // ----------ex4
        // ------st6
        // -------cex
        // --------st5
        // ---------ex5
        Status st = st(ex(cex(st(cex(mst(ex(), st(cex(mst(ex(), st(ex()), st(ex())))), st(cex(st(ex())))))))));
        // #expected output
        // st9
        // -st8
        // --mst7
        // ---ex1
        // ---st4
        // ----mst3
        // -----ex2
        // ----st1
        // -----ex3
        // ----st2
        // -----ex4
        // ---st6
        // ----st5
        // -----ex5
        org.eclipse.epp.logging.aeri.core.IStatus st9 = Reports.newStatus(st);
        IThrowable ex6 = st9.getException();
        org.eclipse.epp.logging.aeri.core.IStatus st8 = st9.getChildren().get(0);
        org.eclipse.epp.logging.aeri.core.IStatus mst7 = st8.getChildren().get(0);
        org.eclipse.epp.logging.aeri.core.IStatus st4 = mst7.getChildren().get(0);
        org.eclipse.epp.logging.aeri.core.IStatus mst3 = st4.getChildren().get(0);
        org.eclipse.epp.logging.aeri.core.IStatus st2 = mst3.getChildren().get(1);
        IThrowable ex4 = st2.getException();
        org.eclipse.epp.logging.aeri.core.IStatus st6 = mst7.getChildren().get(1);
        org.eclipse.epp.logging.aeri.core.IStatus st5 = st6.getChildren().get(0);
        IThrowable ex5 = st5.getException();

        assertThat(st9.getMessage(), is("st9"));
        assertThat(ex6.getMessage(), is("ex6"));
        assertThat(st8.getMessage(), is("st8 [detached from CoreException of Status 'st9' by Error Reporting]"));
        assertThat(mst7.getMessage(), is("mst7 [detached from CoreException of Status 'st8' by Error Reporting]"));
        assertThat(st4.getMessage(), is("st4"));
        assertThat(mst3.getMessage(), is("mst3 [detached from CoreException of Status 'st4' by Error Reporting]"));
        assertThat(st2.getMessage(), is("st2"));
        assertThat(ex4.getMessage(), is("ex4"));
        assertThat(st6.getMessage(), is("st6"));
        assertThat(st5.getMessage(), is("st5 [detached from CoreException of Status 'st6' by Error Reporting]"));
        assertThat(ex5.getMessage(), is("ex5"));
    }

    @Test
    public void testPrettyPrintNullSafe1() {
        IReport report = eFac.createReport();
        Reports.toPrettyString(report);
    }

    @Test
    public void testPrettyPrintNullSafe2() {
        IReport report = eFac.createReport();
        report.setStatus(eFac.createStatus());
        Reports.toPrettyString(report);
    }

    @Test
    public void testPrettyPrintNullSafe3() {
        IReport report = eFac.createReport();
        report.setStatus(eFac.createStatus());
        IThrowable t = eFac.createThrowable();
        t.setClassName("org.test");
        report.getStatus().setException(t);
        Reports.toPrettyString(report);
    }

    @Test
    public void testPrettyPrintSkipsNullException() {
        IReport report = eFac.createReport();
        report.setStatus(eFac.createStatus());
        String prettyPrint = Reports.toPrettyString(report);
        assertThat(prettyPrint, not(containsString("Exception")));
    }

    @Test
    public void testMultistatusMainStacktracesNotFiltered() {

        Exception e1 = new Exception("Stack Trace");
        java.lang.StackTraceElement[] stackTrace = createStacktraceForClasses("java.lang.Thread",
                "org.eclipse.epp.logging.aeri.ui.actions.UiFreezeAction", "org.eclipse.ui.internal.PluginAction",
                "org.eclipse.ui.internal.WWinPluginAction", "org.eclipse.jface.action.ActionContributionItem",
                "org.eclipse.jface.action.ActionContributionItem", "org.eclipse.jface.action.ActionContributionItem",
                "org.eclipse.swt.widgets.EventTable", "org.eclipse.swt.widgets.Display", "org.eclipse.swt.widgets.Widget",
                "org.eclipse.swt.widgets.Display", "org.eclipse.swt.widgets.Display",
                "org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine", "org.eclipse.core.databinding.observable.Realm",
                "org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine", "org.eclipse.e4.ui.internal.workbench.E4Workbench",
                "org.eclipse.ui.internal.Workbench", "org.eclipse.core.databinding.observable.Realm", "org.eclipse.ui.internal.Workbench",
                "org.eclipse.ui.PlatformUI", "org.eclipse.ui.internal.ide.application.IDEApplication",
                "org.eclipse.equinox.internal.app.EclipseAppHandle", "org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher",
                "org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher", "org.eclipse.core.runtime.adaptor.EclipseStarter",
                "org.eclipse.core.runtime.adaptor.EclipseStarter", "sun.reflect.NativeMethodAccessorImpl",
                "sun.reflect.NativeMethodAccessorImpl", "sun.reflect.DelegatingMethodAccessorImpl", "java.lang.reflect.Method",
                "org.eclipse.equinox.launcher.Main", "org.eclipse.equinox.launcher.Main", "org.eclipse.equinox.launcher.Main",
                "org.eclipse.equinox.launcher.Main", "org.eclipse.equinox.launcher.Main");
        e1.setStackTrace(stackTrace);
        IStatus s1 = new Status(IStatus.ERROR, "org.eclipse.ui.monitoring",
                "Sample at 11:25:04.447 (+1,331s)\n" + "Thread 'main' tid=1 (TIMED_WAITING)", e1);

        IStatus multi = new MultiStatus("org.eclipse.ui.monitoring", 0, new IStatus[] { s1 }, "UI freeze of 6,0s at 11:24:59.108",
                new RuntimeException("stand-in-stacktrace"));
        org.eclipse.epp.logging.aeri.core.IStatus newStatus = Reports.newStatus(multi);
        assertThat(newStatus.getChildren().size(), is(1));
        assertThat(newStatus.getChildren().get(0).getException().getStackTrace().size(), is(stackTrace.length));
    }

    private static int numberOfStatusObjects(org.eclipse.epp.logging.aeri.core.IStatus status) {
        final AtomicInteger counter = new AtomicInteger();
        ModelSwitch<AtomicInteger> visitor = new ModelSwitch<AtomicInteger>() {

            @Override
            public AtomicInteger caseStatus(org.eclipse.epp.logging.aeri.core.IStatus object) {
                counter.incrementAndGet();
                return counter;
            }

            @Override
            public AtomicInteger caseThrowable(IThrowable object) {
                return counter;
            }
        };

        visitor.doSwitch(status);
        for (TreeIterator<EObject> it = getAllContents(status, true); it.hasNext();) {
            visitor.doSwitch(it.next());
        }
        return counter.get();
    }

    private static int exCounter = 1;

    private static Exception ex() {
        return ex(null);
    }

    private static Exception cex(IStatus st) {
        return new CoreException(st);
    }

    private static Exception ex(Exception cause) {
        return new Exception("ex" + exCounter++, cause);
    }

    private static int stCounter = 1;

    private static Status st(Exception ex) {
        return new Status(IStatus.ERROR, "org.eclipse", "st" + stCounter++, ex);
    }

    private static MultiStatus mst(Exception ex, Status... status) {
        return new MultiStatus("org.eclipse", IStatus.ERROR, status, "mst" + stCounter++, ex);
    }

}
