// Copyright (C) 2017 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.index.project;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.index.FieldDef.storedOnly;

import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.index.FieldDef;
import com.google.gerrit.index.IndexedField;
import com.google.gerrit.index.RefState;
import com.google.gerrit.index.SchemaUtil;

/**
 * Index schema for projects.
 *
 * <p>Note that this class does not override {@link Object#equals(Object)}. It relies on instances
 * being singletons so that the default (i.e. reference) comparison works.
 */
public class ProjectField {
  private static byte[] toRefState(Project project) {
    return RefState.create(RefNames.REFS_CONFIG, project.getConfigRefState())
        .toByteArray(project.getNameKey());
  }

  public static final IndexedField<ProjectData, String> NAME_FIELD =
      IndexedField.<ProjectData>stringBuilder("RepoName")
          .required()
          .size(200)
          .stored()
          .build(p -> p.getProject().getName());

  public static final IndexedField<ProjectData, String>.SearchSpec NAME_SPEC =
      NAME_FIELD.exact("name");

  public static final IndexedField<ProjectData, String> DESCRIPTION_FIELD =
      IndexedField.<ProjectData>stringBuilder("Description")
          .stored()
          .build(p -> p.getProject().getDescription());

  public static final IndexedField<ProjectData, String>.SearchSpec DESCRIPTION_SPEC =
      DESCRIPTION_FIELD.fullText("description");

  public static final IndexedField<ProjectData, String> PARENT_NAME_FIELD =
      IndexedField.<ProjectData>stringBuilder("ParentName")
          .build(p -> p.getProject().getParentName());

  public static final IndexedField<ProjectData, String>.SearchSpec PARENT_NAME_SPEC =
      PARENT_NAME_FIELD.exact("parent_name");

  public static final IndexedField<ProjectData, Iterable<String>> NAME_PART_FIELD =
      IndexedField.<ProjectData>iterableStringBuilder("NamePart")
          .size(200)
          .build(p -> SchemaUtil.getNameParts(p.getProject().getName()));

  public static final IndexedField<ProjectData, Iterable<String>>.SearchSpec NAME_PART_SPEC =
      NAME_PART_FIELD.prefix("name_part");

  public static final IndexedField<ProjectData, String> STATE_FIELD =
      IndexedField.<ProjectData>stringBuilder("State")
          .stored()
          .build(p -> p.getProject().getState().name());

  public static final IndexedField<ProjectData, String>.SearchSpec STATE_SPEC =
      STATE_FIELD.exact("state");

  public static final IndexedField<ProjectData, Iterable<String>> ANCESTOR_NAME_FIELD =
      IndexedField.<ProjectData>iterableStringBuilder("AncestorName")
          .build(ProjectData::getParentNames);

  public static final IndexedField<ProjectData, Iterable<String>>.SearchSpec ANCESTOR_NAME_SPEC =
      ANCESTOR_NAME_FIELD.exact("ancestor_name");

  /**
   * All values of all refs that were used in the course of indexing this document. This covers
   * {@code refs/meta/config} of the current project and all of its parents.
   *
   * <p>Emitted as UTF-8 encoded strings of the form {@code project:ref/name:[hex sha]}.
   */
  public static final FieldDef<ProjectData, Iterable<byte[]>> REF_STATE =
      storedOnly("ref_state")
          .buildRepeatable(
              projectData ->
                  projectData.tree().stream()
                      .filter(p -> p.getProject().getConfigRefState() != null)
                      .map(p -> toRefState(p.getProject()))
                      .collect(toImmutableList()));
}
