// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gerrit.server.change;

import com.google.common.base.Splitter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.server.AccountExternalIdAccess;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.util.CharArraySet;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.IntField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
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.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;
import org.eclipse.jgit.lib.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
/**
 * The suggest oracle may be called many times in rapid succession during the
 * course of one operation.
 * It would be easy to have a simple Cache<Boolean, List<Account>> with a short
 * expiration time of 30s.
 * Cache only has a single key we're just using Cache for the expiration behavior.
 */
@Singleton
public class ReviewerSuggestionCache {
  private static final Logger log = LoggerFactory
      .getLogger(ReviewerSuggestionCache.class);

  private static final String ID = "id";
  private static final String NAME = "name";
  private static final String EMAIL = "email";
  private static final String USERNAME = "username";
  private static final String[] ALL = {ID, NAME, EMAIL, USERNAME};

  private final LoadingCache<Boolean, IndexSearcher> cache;
  private final Provider<ReviewDb> db;

  @Inject
  ReviewerSuggestionCache(Provider<ReviewDb> db,
      @GerritServerConfig Config cfg) {
    this.db = db;
    long expiration = ConfigUtil.getTimeUnit(cfg,
        "suggest", null, "fullTextSearchRefresh",
        TimeUnit.HOURS.toMillis(1),
        TimeUnit.MILLISECONDS);
    this.cache =
        CacheBuilder.newBuilder().maximumSize(1)
            .expireAfterWrite(expiration, TimeUnit.MILLISECONDS)
            .build(new CacheLoader<Boolean, IndexSearcher>() {
              @Override
              public IndexSearcher load(Boolean key) throws Exception {
                return index();
              }
            });
  }

  List<AccountInfo> search(String query, int n) throws IOException {
    IndexSearcher searcher = get();
    if (searcher == null) {
      return Collections.emptyList();
    }

    List<String> segments = Splitter.on(' ').omitEmptyStrings().splitToList(
        query.toLowerCase());
    BooleanQuery q = new BooleanQuery();
    for (String field : ALL) {
      BooleanQuery and = new BooleanQuery();
      for (String s : segments) {
        and.add(new PrefixQuery(new Term(field, s)), Occur.MUST);
      }
      q.add(and, Occur.SHOULD);
    }

    TopDocs results = searcher.search(q, n);
    ScoreDoc[] hits = results.scoreDocs;

    List<AccountInfo> result = new LinkedList<>();

    for (ScoreDoc h : hits) {
      Document doc = searcher.doc(h.doc);

      AccountInfo info = new AccountInfo(
          doc.getField(ID).numericValue().intValue());
      info.name = doc.get(NAME);
      info.email = doc.get(EMAIL);
      info.username = doc.get(USERNAME);
      result.add(info);
    }

    return result;
  }

  private IndexSearcher get() {
    try {
      return cache.get(true);
    } catch (ExecutionException e) {
      log.warn("Cannot fetch reviewers from cache", e);
      return null;
    }
  }

  private IndexSearcher index() throws IOException, OrmException {
    RAMDirectory idx = new RAMDirectory();
    @SuppressWarnings("deprecation")
    IndexWriterConfig config = new IndexWriterConfig(
        Version.LUCENE_4_10_1,
        new StandardAnalyzer(CharArraySet.EMPTY_SET));
    config.setOpenMode(OpenMode.CREATE);

    try (IndexWriter writer = new IndexWriter(idx, config)) {
      for (Account a : db.get().accounts().all()) {
        if (a.isActive()) {
          addAccount(writer, a);
        }
      }
    }

    return new IndexSearcher(DirectoryReader.open(idx));
  }

  private void addAccount(IndexWriter writer, Account a)
      throws IOException, OrmException {
    Document doc = new Document();
    doc.add(new IntField(ID, a.getId().get(), Store.YES));
    if (a.getFullName() != null) {
      doc.add(new TextField(NAME, a.getFullName(), Store.YES));
    }
    if (a.getPreferredEmail() != null) {
      doc.add(new TextField(EMAIL, a.getPreferredEmail(), Store.YES));
      doc.add(new StringField(EMAIL, a.getPreferredEmail().toLowerCase(),
          Store.YES));
    }
    AccountExternalIdAccess extIdAccess = db.get().accountExternalIds();
    String username = AccountState.getUserName(
        extIdAccess.byAccount(a.getId()).toList());
    if (username != null) {
      doc.add(new StringField(USERNAME, username, Store.YES));
    }
    writer.addDocument(doc);
  }
}
