/**
 * Copyright (c) 2015 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
 */
package org.eclipse.epp.internal.logging.aeri.ide.server.mars;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.alwaysFalse;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.eclipse.epp.internal.logging.aeri.ide.IIdePackage.*;
import static org.eclipse.epp.internal.logging.aeri.ide.processors.AnonymizeStackTracesProcessor.CTX_ACCEPTED_PACKAGES_PATTERNS;
import static org.eclipse.epp.logging.aeri.core.IModelPackage.*;
import static org.eclipse.epp.logging.aeri.core.util.Formats.format;
import static org.eclipse.epp.logging.aeri.core.util.Links.*;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.fluent.Executor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.epp.internal.logging.aeri.ide.IServerDescriptor;
import org.eclipse.epp.internal.logging.aeri.ide.l10n.LogMessages;
import org.eclipse.epp.internal.logging.aeri.ide.l10n.Messages;
import org.eclipse.epp.internal.logging.aeri.ide.server.LocalReportsHistory;
import org.eclipse.epp.internal.logging.aeri.ide.server.LocalReportsHistory.LocalHistorySeenFilter;
import org.eclipse.epp.internal.logging.aeri.ide.server.rest.RestBasedProblemsHistory;
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.IReportProcessor;
import org.eclipse.epp.logging.aeri.core.ISendOptions;
import org.eclipse.epp.logging.aeri.core.IServerConnection;
import org.eclipse.epp.logging.aeri.core.ISystemSettings;
import org.eclipse.epp.logging.aeri.core.ProblemStatus;
import org.eclipse.epp.logging.aeri.core.SendMode;
import org.eclipse.epp.logging.aeri.core.filters.AcceptFreezeFilter;
import org.eclipse.epp.logging.aeri.core.filters.AcceptedPluginsFilter;
import org.eclipse.epp.logging.aeri.core.filters.AcceptedProductsFilter;
import org.eclipse.epp.logging.aeri.core.filters.DecoratingDebugFilter;
import org.eclipse.epp.logging.aeri.core.filters.RequiredPackagesFilter;
import org.eclipse.epp.logging.aeri.core.filters.StatusIgnorePatternsFilter;
import org.eclipse.epp.logging.aeri.core.util.Formats;
import org.eclipse.epp.logging.aeri.core.util.Logs;
import org.eclipse.epp.logging.aeri.core.util.Reports;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.util.concurrent.AbstractIdleService;

public class ServerConnection extends AbstractIdleService implements IServerConnection {

    private final class UpdateDatabaseOnFeatureChangeAdapter extends AdapterImpl {
        private final Class<?> featureClass;
        private final int[] observedFeatureIds;

        UpdateDatabaseOnFeatureChangeAdapter(Class<?> featureClass, int... observedFeatureIds) {
            this.featureClass = featureClass;
            this.observedFeatureIds = observedFeatureIds;
        }

        @Override
        public void notifyChanged(Notification msg) {
            int featureID = msg.getFeatureID(featureClass);
            if (msg.getEventType() == Notification.SET && ArrayUtils.contains(observedFeatureIds, featureID)) {
                if (!shouldUse()) {
                    return;
                }
                for (IProblemsHistory remoteHistory : remoteHistories) {
                    remoteHistory.sync(io, systemSettings);
                }
            }
        }
    }

    private final IServerDescriptor server;
    private final ISystemSettings systemSettings;
    private final File configurationArea;
    private Predicate<IStatus> statusFilters = alwaysFalse();
    private IO io;
    private LocalReportsHistory localHistory;
    private final List<IProblemsHistory> remoteHistories = new ArrayList<>();

    @Inject
    public ServerConnection(IServerDescriptor descriptor, ISystemSettings system, File configurationArea) {
        this.systemSettings = checkNotNull(system);
        this.configurationArea = checkNotNull(configurationArea);
        this.server = checkNotNull(descriptor);
    }

    @PostConstruct
    private void e4Start() {
        startAsync();
    }

    @Override
    protected void startUp() throws Exception {
        try {
            {
                File file = new File(configurationArea, "server-config.json"); //$NON-NLS-1$
                io = createIO(file);
                if (file.exists()) {
                    io.loadConfiguration();
                }
                if (io.isConfigurationOutdated()) {
                    io.refreshConfiguration(checkNotNull(getLink(server, REL_DISCOVERY)).getHref(), new NullProgressMonitor());
                    io.saveConfiguration();
                }
            }

            {
                File localHistoryStateLocation = new File(configurationArea, "local-history"); //$NON-NLS-1$
                localHistoryStateLocation.mkdirs();
                localHistory = new LocalReportsHistory(localHistoryStateLocation);
                localHistory.startAsync();
            }

            {
                if (io.getConfiguration().getInterestUrl() != null) {
                    File cacheDir = new File(configurationArea, "http-cache");
                    cacheDir.mkdirs();
                    remoteHistories.add(createRestBasedProblemsHistory(cacheDir));
                }
                if (io.getConfiguration().getProblemsUrl() != null) {
                    remoteHistories.add(createServerProblemsHistory());
                }

                if (shouldUse()) {
                    for (IProblemsHistory remoteHistory : remoteHistories) {
                        remoteHistory.sync(io, systemSettings);
                    }
                }

                server.eAdapters().add(new UpdateDatabaseOnFeatureChangeAdapter(IServerDescriptor.class, SERVER_DESCRIPTOR__ENABLED,
                        SERVER_DESCRIPTOR__CONFIGURED));
                systemSettings.eAdapters().add(new UpdateDatabaseOnFeatureChangeAdapter(ISystemSettings.class, SYSTEM_SETTINGS__CONFIGURED,
                        SYSTEM_SETTINGS__SEND_MODE));
            }

            {
                // make sure we can operate before removing the AlwaysFalse filter...
                ServerConfiguration configuration = io.getConfiguration();
                checkNotNull(configuration, "no configuration available"); //$NON-NLS-1$
                checkNotNull(localHistory);

                @SuppressWarnings("unchecked")
                Predicate<? super IStatus>[] statusFilters = DecoratingDebugFilter.decorate(
                // @formatter:off
                new LocalHistorySeenFilter(localHistory, systemSettings),
                new AcceptedProductsFilter(configuration.getAcceptedProductsPatterns()),
                new RequiredPackagesFilter(configuration.getRequiredPackagesPatterns()),
                new AcceptedPluginsFilter(configuration.getAcceptedPluginsPatterns()),
                new StatusIgnorePatternsFilter(configuration.getIgnoredPluginMessagesPatterns()),
                new AcceptFreezeFilter(configuration.isAcceptUiFreezes())
                // @formatter:on
                );
                this.statusFilters = Predicates.and(statusFilters);
            }
        } catch (Exception e) {
            Logs.log(LogMessages.WARN_SERVER_FAILURE, e, server.getId(), e.getMessage());
            // IdleService is missing proper means to set state to FAILED.
            // If something went wrong, at least set its state to !RUNNNING
            stopAsync();
        }
    }

    private IProblemsHistory createRestBasedProblemsHistory(File cacheDir) throws IOException {
        return new RestBasedProblemsHistory(io.getConfiguration(), cacheDir);
    }

    @VisibleForTesting
    protected IProblemsHistory createServerProblemsHistory() {
        File remoteHistoryStateLocation = new File(configurationArea, "remote-history"); //$NON-NLS-1$
        ProblemsDatabaseProblemsHistory remoteHistory = new ProblemsDatabaseProblemsHistory(remoteHistoryStateLocation);
        remoteHistory.startAsync();
        return remoteHistory;
    }

    private boolean shouldUse() {
        if (!systemSettings.isConfigured() || systemSettings.getSendMode() == SendMode.NEVER) {
            return false;
        }
        if (!server.isConfigured() || !server.isEnabled()) {
            return false;
        }
        return true;
    }

    @VisibleForTesting
    protected IO createIO(File file) {
        return new IO(Executor.newInstance(), file);
    }

    @Override
    public IProblemState interested(IStatus status, IEclipseContext context, IProgressMonitor monitor) {
        if (!isRunning() || !statusFilters.apply(status)) {
            IProblemState res = IModelFactory.eINSTANCE.createProblemState();
            res.setStatus(ProblemStatus.IGNORED);
            return res;
        } else if (!shouldUse()) {
            // FIXME
            // This prevents remote requests (IProblemsHistory.seen ) to the server before Aeri has been enabled by the user.
            // The downside is that problems that occur before Aeri is enabled will be shown as unconfirmed.
            // Ideally, once Aeri is enabled, the server is queried and the response is used. This requires bigger changes in the control
            // flow however.
            return problemStateUnconfirmedBeforeSend();
        } else {
            IProblemState seen = null;
            for (IProblemsHistory remoteHistory : remoteHistories) {
                seen = remoteHistory.seen(status).orNull();
                if (seen == null) {
                    continue;
                }

                String message = seen.getMessage();
                if (seen.getMessage() != null) {
                    return seen;
                }
                switch (seen.getStatus()) {
                case IGNORED:
                    return seen;
                case NEEDINFO:
                    message = msgNeedinfoBeforeSend(seen);
                    break;
                case WONTFIX:
                    message = msgWontFixBeforeSend(seen);
                    break;
                case FIXED:
                    message = msgFixedBeforeSend(seen);
                    break;
                case UNCONFIRMED:
                    message = msgUnconfirmedBeforeSend();
                    break;
                default:
                    message = Formats.format("Unexpected state {0}", seen.getStatus()); //$NON-NLS-1$
                }
                seen.setMessage(message);
                break;
            }
            if (seen == null) {
                return problemStateUnconfirmedBeforeSend();
            }
            return seen;
        }
    }

    private IProblemState problemStateUnconfirmedBeforeSend() {
        IProblemState res = IModelFactory.eINSTANCE.createProblemState();
        res.setStatus(ProblemStatus.UNCONFIRMED);
        res.setMessage(msgUnconfirmedBeforeSend());
        return res;
    }

    @Override
    public IReport transform(IStatus status, IEclipseContext context) {
        // set the accepted patterns for the AnonymizeStackTracesProcessor
        context.set(CTX_ACCEPTED_PACKAGES_PATTERNS, io.getConfiguration().getAcceptedPackagesPatterns());

        ISendOptions options = checkNotNull(context.get(ISendOptions.class));
        IReport report = Reports.newReport(status);
        report.setComment(options.getComment());
        for (IReportProcessor processor : options.getEnabledProcessors()) {
            processor.process(report, status, context);
        }
        report.setAnonymousId(options.getReporterId());
        report.setName(options.getReporterName());
        report.setEmail(options.getReporterEmail());
        report.setSeverity(options.getSeverity());
        return report;
    }

    @Override
    public IProblemState submit(IStatus status, IEclipseContext context, IProgressMonitor monitor) throws IOException {
        IReport report = transform(status, context);
        IProblemState response = io.upload(report, monitor);
        localHistory.remember(status);

        String message = response.getMessage();
        if (isNotBlank(message)) {
            message = StringUtils.replace(message, "{link,", "{0,link,");
            message = format(message, response);
            message = format(Messages.PROBLEM_MESSAGES_FORWARD_SERVER_RESPONSE, server.getName(), message);
            response.setMessage(message);
            return response;
        }
        switch (response.getStatus()) {
        case NEW:
            message = msgNewAfterSend(response);
            break;
        case UNCONFIRMED:
            message = msgUnconfirmedAfterSend(response);
            break;
        case CONFIRMED:
            message = msgConfirmedAfterSend(response);
            break;
        case FIXED:
            message = msgFixedAfterSend(response);
            break;
        case NEEDINFO:
            message = msgNeedinfoAfterSend(response);
            break;
        case FAILURE:
            message = msgFailure();
            break;
        case IGNORED:
        case INVALID:
            message = msgInvalidOrIgnored(response);
            break;
        }
        response.setMessage(message);
        return response;
    }

    private String msgFailure() {
        return format(Messages.PROBLEM_MESSAGES_SERVER_FAILURE, server.getName());
    }

    private String msgInvalidOrIgnored(IProblemState response) {
        return format(Messages.PROBLEM_MESSAGES_IGNORED_OR_INVALID_STATUS, server.getName(), response);
    }

    @Override
    public void discarded(IStatus status, IEclipseContext context) {
        localHistory.remember(status);
    }

    protected String msgNewAfterSend(IProblemState response) {
        return format(Messages.PROBLEM_MESSAGES_NEW_AFTER_SEND, server.getName(), response);
    }

    protected String msgUnconfirmedBeforeSend() {
        return format(Messages.PROBLEM_MESSAGES_UNCONFIRMED_BEFORE_SEND, server.getName());
    }

    protected String msgUnconfirmedAfterSend(IProblemState response) {
        return format(Messages.PROBLEM_MESSAGES_UNCONFIRMED_AFTER_SEND, server.getName(), response);
    }

    protected String msgConfirmedAfterSend(IProblemState response) {
        if (hasLink(response, REL_BUG)) {
            return format(Messages.PROBLEM_MESSAGES_CONFIRMED_BUG_AFTER_SEND, server.getName(), response);
        }
        return format(Messages.PROBLEM_MESSAGES_CONFIRMED_NO_BUG_AFTER_SEND, server.getName(), response);
    }

    protected String msgNeedinfoBeforeSend(IProblemState cachedState) {
        if (hasLink(cachedState, REL_BUG)) {
            return Formats.format(Messages.PROBLEM_MESSAGES_NEEDINFO_BUG_BEFORE_SEND, server.getName(), cachedState);
        }
        return Formats.format(Messages.PROBLEM_MESSAGES_NEEDINFO_NO_BUG_BEFORE_SEND, server.getName(), cachedState);
    }

    protected String msgWontFixBeforeSend(IProblemState cachedState) {
        if (hasLink(cachedState, REL_BUG)) {
            return Formats.format(Messages.PROBLEM_MESSAGES_WONTFIX_BUG_BEFORE_SEND, server.getName(), cachedState);
        }
        return Formats.format(Messages.PROBLEM_MESSAGES_WONTFIX_NO_BUG_BEFORE_SEND, server.getName(), cachedState);
    }

    protected String msgNeedinfoAfterSend(IProblemState response) {
        if (hasLink(response, REL_BUG)) {
            return Formats.format(Messages.PROBLEM_MESSAGES_NEEDINFO_BUG_AFTER_SEND, server.getName(), response);
        }
        return Formats.format(Messages.PROBLEM_MESSAGES_NEEDINFO_NO_BUG_AFTER_SEND, server.getName(), response);
    }

    protected String msgFixedBeforeSend(IProblemState cachedState) {
        if (hasLink(cachedState, REL_BUG)) {
            return Formats.format(Messages.PROBLEM_MESSAGES_FIXED_BUG_BEFORE_SEND, server.getName(), cachedState);
        }
        return format(Messages.PROBLEM_MESSAGES_FIXED_NO_BUG_BEFORE_SEND, server.getName(), cachedState);

    }

    protected String msgFixedAfterSend(IProblemState response) {
        if (hasLink(response, REL_BUG)) {
            return format(Messages.PROBLEM_MESSAGES_FIXED_BUG_AFTER_SEND, server.getName(), response);
        }
        return format(Messages.PROBLEM_MESSAGES_FIXED_NO_BUG_AFTER_SEND, server.getName(), response);
    }

    @PreDestroy
    private void diStop() throws TimeoutException {
        stopAsync().awaitTerminated(2, SECONDS);
    }

    @Override
    protected void shutDown() throws Exception {
        for (IProblemsHistory remoteHistory : remoteHistories) {
            remoteHistory.close();
        }
    }

    @Override
    public String toString() {
        return server.getId() + " " + super.toString(); //$NON-NLS-1$
    }
}
