package aeri.rcp;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import static org.eclipse.epp.logging.aeri.core.util.Links.*;

import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.epp.logging.aeri.core.IModelFactory;
import org.eclipse.epp.logging.aeri.core.IProblemState;
import org.eclipse.epp.logging.aeri.core.IReport;
import org.eclipse.epp.logging.aeri.core.ISendOptions;
import org.eclipse.epp.logging.aeri.core.ProblemStatus;
import org.eclipse.epp.logging.aeri.core.util.Reports;
import org.eclipse.epp.logging.aeri.core.util.Statuses;

import com.google.common.base.Joiner;

/**
 * Primitive, not fully implemented notification service. For illustration purpose only.
 */
public class DemoServerConnection implements org.eclipse.epp.logging.aeri.core.IServerConnection {

    @SuppressWarnings("null")
    @Override
    public IProblemState interested(IStatus status, IEclipseContext context, IProgressMonitor monitor) {
        IProblemState state = IModelFactory.eINSTANCE.createProblemState();
        int nextInt = new Random().nextInt(5);
        ProblemStatus randomStatus = ProblemStatus.get(nextInt);
        state.setStatus(randomStatus);
        addLink(state, REL_BUG, "http://eclipse.org", "Bug #12345");
        state.setMessage(StringUtils.repeat(status.getMessage(), 2));

        Throwable exception = status.getException();
        StackTraceElement[] normalized = Statuses.normalize(exception);
        StackTraceElement[] truncate = Statuses.truncate(normalized);

        List<String> stes = new LinkedList<>();
        for (StackTraceElement frame : truncate) {
            stes.add(frame.toString());
        }
        String join = Joiner.on("\n  at ").join(stes);
        System.out.println(join);
        return state;
    }

    @Override
    public IReport transform(IStatus status, IEclipseContext context) {
        ISendOptions options = checkNotNull(context.get(ISendOptions.class));
        IReport report = Reports.newReport(status);
        report.setComment(options.getComment());
        report.setAnonymousId(options.getReporterId());
        report.setName(options.getReporterName());
        report.setEmail(options.getReporterEmail());
        report.setSeverity(options.getSeverity());

        if (options.isAnonymizeMessages()) {
            Reports.anonymizeMessages(report);
        }
        if (options.isAnonymizeStackTraces()) {
            Reports.anonymizeStackTraces(report, newArrayList(Pattern.compile("org\\.eclipse\\..*")));
        }
        return report;
    }

    @Override
    public IProblemState submit(IStatus status, IEclipseContext context, IProgressMonitor monitor) throws IOException {
        IProblemState response = IModelFactory.eINSTANCE.createProblemState();
        addLink(response, REL_BUG, "http://eclipse.org", "Bug #12345");
        addLink(response, REL_SUBMISSION, "http://localhost/does-not-exist", "Submission");
        {
            // RANDOM :-)
            int nextInt = new Random().nextInt(5);
            ProblemStatus randomStatus = ProblemStatus.get(nextInt);
            response.setStatus(randomStatus);
        }
        return response;
    }

    @Override
    public void discarded(IStatus status, IEclipseContext context) {
        System.out.println("DISCARDED:\n\n" + status);

    }
}
