// Copyright (C) 2016 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.lucene;

import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.gerrit.lucene.LuceneChangeIndex.ID_STR_SORT_FIELD;
import static com.google.gerrit.lucene.LuceneChangeIndex.MERGED_ON_SORT_FIELD;
import static com.google.gerrit.lucene.LuceneChangeIndex.UPDATED_SORT_FIELD;
import static com.google.gerrit.server.index.change.ChangeSchemaDefinitions.NAME;

import com.google.common.collect.ImmutableSet;
import com.google.gerrit.entities.Change;
import com.google.gerrit.index.QueryOptions;
import com.google.gerrit.index.Schema;
import com.google.gerrit.index.Schema.Values;
import com.google.gerrit.index.SchemaFieldDefs.SchemaField;
import com.google.gerrit.index.query.DataSource;
import com.google.gerrit.index.query.FieldBundle;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.QueryParseException;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.index.change.ChangeIndex;
import com.google.gerrit.server.index.options.AutoFlush;
import com.google.gerrit.server.query.change.ChangeData;
import java.io.IOException;
import java.nio.file.Path;
import java.sql.Timestamp;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.search.SearcherFactory;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

public class ChangeSubIndex extends AbstractLuceneIndex<Change.Id, ChangeData>
    implements ChangeIndex {
  ChangeSubIndex(
      Schema<ChangeData> schema,
      SitePaths sitePaths,
      Path path,
      ImmutableSet<String> skipFields,
      GerritIndexWriterConfig writerConfig,
      SearcherFactory searcherFactory,
      AutoFlush autoFlush)
      throws IOException {
    this(
        schema,
        sitePaths,
        FSDirectory.open(path),
        path.getFileName().toString(),
        skipFields,
        writerConfig,
        searcherFactory,
        autoFlush);
  }

  ChangeSubIndex(
      Schema<ChangeData> schema,
      SitePaths sitePaths,
      Directory dir,
      String subIndex,
      ImmutableSet<String> skipFields,
      GerritIndexWriterConfig writerConfig,
      SearcherFactory searcherFactory,
      AutoFlush autoFlush)
      throws IOException {
    super(
        schema,
        sitePaths,
        dir,
        NAME,
        skipFields,
        subIndex,
        writerConfig,
        searcherFactory,
        autoFlush);
  }

  @Override
  public void insert(ChangeData obj) {
    throw new UnsupportedOperationException("don't use ChangeSubIndex directly");
  }

  @Override
  public void replace(ChangeData obj) {
    throw new UnsupportedOperationException("don't use ChangeSubIndex directly");
  }

  @Override
  public void delete(Change.Id key) {
    throw new UnsupportedOperationException("don't use ChangeSubIndex directly");
  }

  @Override
  public DataSource<ChangeData> getSource(Predicate<ChangeData> p, QueryOptions opts)
      throws QueryParseException {
    throw new UnsupportedOperationException("don't use ChangeSubIndex directly");
  }

  // Make method public so that it can be used in LuceneChangeIndex
  @Override
  public FieldBundle toFieldBundle(Document doc) {
    return super.toFieldBundle(doc);
  }

  @Override
  void add(Document doc, Values<ChangeData> values) {
    // Add separate DocValues fields for those fields needed for sorting.
    SchemaField<ChangeData, ?> f = values.getField();
    if (f == ChangeField.NUMERIC_ID_STR_SPEC) {
      String v = (String) getOnlyElement(values.getValues());
      doc.add(new NumericDocValuesField(ID_STR_SORT_FIELD, Integer.valueOf(v)));
    } else if (f == ChangeField.UPDATED_SPEC) {
      long t = ((Timestamp) getOnlyElement(values.getValues())).getTime();
      doc.add(new NumericDocValuesField(UPDATED_SORT_FIELD, t));
    } else if (f == ChangeField.MERGED_ON_SPEC) {
      long t = ((Timestamp) getOnlyElement(values.getValues())).getTime();
      doc.add(new NumericDocValuesField(MERGED_ON_SORT_FIELD, t));
    }
    super.add(doc, values);
  }

  @Override
  protected ChangeData fromDocument(Document doc) {
    throw new UnsupportedOperationException("don't use ChangeSubIndex directly");
  }
}
