/**
 * 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;

import static com.google.common.base.Preconditions.*;
import static org.apache.commons.lang3.StringUtils.abbreviateMiddle;
import static org.eclipse.epp.internal.logging.aeri.ide.l10n.LogMessages.*;
import static org.eclipse.epp.logging.aeri.core.SystemControl.isDebug;
import static org.eclipse.epp.logging.aeri.core.util.Logs.log;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.apache.lucene.analysis.core.KeywordAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.SearcherManager;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.IOUtils;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.epp.internal.logging.aeri.ide.l10n.Messages;
import org.eclipse.epp.logging.aeri.core.SystemControl;
import org.eclipse.epp.logging.aeri.core.util.Statuses;

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

/**
 * A history of all problems this client sent before.
 */
public class LocalReportsHistory extends AbstractIdleService {

    private static final String F_VERSION = "version"; //$NON-NLS-1$
    private static final String VERSION = "0.6"; //$NON-NLS-1$
    private static final String F_IDENTITY = "identity"; //$NON-NLS-1$
    private File stateLocation;
    private Directory index;
    private IndexWriter writer;
    private SearcherManager manager;

    public LocalReportsHistory(File stateLocation) {
        this.stateLocation = stateLocation;
    }

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

    @Override
    protected void startUp() throws Exception {
        // field assignment for testing
        index = createIndexDirectory();
        createWriter();
        createSearchManager();
    }

    public boolean seen(IStatus status) {
        checkNotNull(status);
        checkState(isRunning());
        String fingerprint = computeHistoryFingerprint(status);
        boolean seen = seen(fingerprint);
        return seen;
    }

    private boolean seen(String fingerprint) {
        TermQuery query = new TermQuery(new Term(F_IDENTITY, fingerprint));
        IndexSearcher searcher = null;
        try {
            searcher = manager.acquire();
            TopDocs results = searcher.search(query, 1);
            boolean foundIdenticalReport = results.totalHits.value > 0;
            return foundIdenticalReport;
        } catch (Exception e) {
            log(WARN_HISTORY_NOT_AVAILABLE, e);
            return false;
        } finally {
            try {
                if (searcher != null) {
                    manager.release(searcher);
                    searcher = null;
                }
            } catch (IOException e) {
                log(WARN_HISTORY_NOT_AVAILABLE, e);
            }
        }
    }

    private static String computeHistoryFingerprint(IStatus status) {
        IStatus relevant = Statuses.findRelevantStatus(status);
        Throwable exception = checkNotNull(relevant.getException());
        StackTraceElement[] normalizes = Statuses.normalize(exception);
        StackTraceElement[] truncated = Statuses.truncate(normalizes);
        String fingerprint = Statuses.newFingerprint(truncated, false);
        return fingerprint;
    }

    public void remember(IStatus status) {
        checkNotNull(status);
        checkState(isRunning());
        doRemember(status);
        reopen();
    }

    private void doRemember(IStatus status) {
        String fingerprint = computeHistoryFingerprint(status);
        if (seen(fingerprint)) {
            return;
        }
        Document doc = new Document();
        Field field = new StringField(F_IDENTITY, fingerprint, Store.NO);
        doc.add(field);
        try {
            writer.addDocument(doc);
            writer.commit();
        } catch (Exception e) {
            log(WARN_HISTORY_NOT_AVAILABLE, e);
        }
        if (isDebug()) {
            log(DEBUG_HISTORY_REMEMBER_STATUS, abbreviateMiddle(status.getMessage(), Messages.LOG_HISTORY_ABBREVIATION, 60), fingerprint,
                    abbreviateMiddle(stateLocation.toString(), Messages.LOG_HISTORY_ABBREVIATION, 60));
        }
    }

    private void reopen() {
        try {
            manager.maybeRefresh();
        } catch (IOException e) {
            log(WARN_HISTORY_NOT_AVAILABLE, e);
        }
    }

    @VisibleForTesting
    protected Directory createIndexDirectory() throws IOException {
        stateLocation.mkdirs();
        index = FSDirectory.open(stateLocation.toPath());
        return index;
    }

    private void createWriter() throws CorruptIndexException, LockObtainFailedException, IOException {
        IndexWriterConfig conf = new IndexWriterConfig(new KeywordAnalyzer());
        conf.setOpenMode(OpenMode.CREATE_OR_APPEND);
        writer = new IndexWriter(index, conf);
        // to build an initial index if empty:
        IndexWriter.DocStats stats = writer.getDocStats();
        if (stats.numDocs == 0) {
            buildInitialIndex();
        }
    }

    private void buildInitialIndex() throws CorruptIndexException, IOException {
        Document meta = new Document();
        meta.add(new StoredField(F_VERSION, VERSION));
        writer.addDocument(meta);
        writer.commit();
    }

    private void createSearchManager() throws IOException {
        manager = new SearcherManager(index, null);
    }

    @PreDestroy
    private void e4Stop() {
        try {
            stopAsync().awaitTerminated(2, TimeUnit.SECONDS);
        } catch (Exception e) {
            log(WARN_HISTORY_STOP_FAILED, e);
        }
    }

    @Override
    protected void shutDown() throws Exception {
        IOUtils.close(writer, index);
        manager.close();
    }

    public static class LocalHistorySeenFilter implements Predicate<IStatus> {

        private LocalReportsHistory history;

        public LocalHistorySeenFilter(LocalReportsHistory history) {
            this.history = history;
        }

        @Override
        public boolean apply(IStatus input) {
            if (SystemControl.isDebug()) {
                return true;
            }
            if (!history.isRunning()) {
                return false;
            }
            return !history.seen(input);
        }
    }
}
