// 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.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 {@code 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();
    IndexWriterConfig config = new IndexWriterConfig(
        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 StringField(EMAIL, a.getPreferredEmail().toLowerCase(),
          Store.YES));
      doc.add(new TextField(EMAIL, a.getPreferredEmail(), 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);
  }
}
