// Copyright (C) 2020 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.plugins.codeowners.backend;

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static java.util.Objects.requireNonNull;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import java.util.Arrays;

/**
 * A code owner set defines a set of code owners for a set of path expressions.
 *
 * <p>The code owners own the files that match any of the path expressions.
 *
 * <p>Code owner sets are stored in {@link CodeOwnerConfig}s which define code owners for the folder
 * in which they are stored.
 *
 * <p>The path expressions are relative to the folder of the {@link CodeOwnerConfig} that contains
 * the owner set.
 *
 * <p>If the set of path expressions is empty the code owners apply for all files in the folder of
 * the {@link CodeOwnerConfig} (including files in sub folders).
 */
@AutoValue
public abstract class CodeOwnerSet {
  /**
   * Gets whether global code owners (code owners from code owner sets without path expression in
   * the same code owner config) and code owners from parent code owner configs (code owner configs
   * in parent folders) should be ignored.
   *
   * <p>Code owner configs are organized hierarchically, e.g. the code owner config at "/" is the
   * parent config of the code owner config at "/foo" which in turn is the parent config of the code
   * owner config at "/foo/bar". Code owners from the parent config can be ignored by setting {@link
   * CodeOwnerConfig#ignoreParentCodeOwners()} on code owner config level.
   *
   * <p>In addition there are 2 hierarchy levels within each code owner config. 1. global code
   * owners applying to all files in the folder (represented by code owner sets without path
   * expressions), 2. per file code owners (represented by code owner sets with path expressions).
   * On per file level it is possible to ignore the global code owners (code owner sets without path
   * expressions) by setting {@link #ignoreGlobalAndParentCodeOwners()} on the code owner set. If
   * {@link #ignoreGlobalAndParentCodeOwners()} is set, implicitly for matching files also all code
   * owners inherited from parent code owner configs are ignored.
   *
   * <p>If a matching code owner set ignores global and parent code owners, matching sibling code
   * owner sets (other code owner sets with matching path expressions in the same code owner config)
   * are still honored.
   */
  public abstract boolean ignoreGlobalAndParentCodeOwners();

  /** Path expressions that match the files that are owned by the {@link #codeOwners()}. */
  public abstract ImmutableSet<String> pathExpressions();

  /** Gets references to the code owner configs that should be imported. */
  public abstract ImmutableSet<CodeOwnerConfigReference> imports();

  /** Gets the code owners of this code owner set. */
  public abstract ImmutableSet<CodeOwnerReference> codeOwners();

  /**
   * Creates a builder from this code owner set.
   *
   * @return builder that was created from this code owner set
   */
  public abstract Builder toBuilder();

  /** Creates a builder for a {@link CodeOwnerSet}. */
  public static CodeOwnerSet.Builder builder() {
    return new AutoValue_CodeOwnerSet.Builder()
        .setIgnoreGlobalAndParentCodeOwners(false)
        .setPathExpressions(ImmutableSet.of());
  }

  /**
   * Creates a {@link CodeOwnerSet} instance without path expressions.
   *
   * @param codeOwners the code owners of the code owner set
   */
  public static CodeOwnerSet createWithoutPathExpressions(
      ImmutableSet<CodeOwnerReference> codeOwners) {
    return builder().setCodeOwners(codeOwners).build();
  }

  /**
   * Creates a {@link CodeOwnerSet} instance without path expressions.
   *
   * @param emails the emails of the code owners
   */
  public static CodeOwnerSet createWithoutPathExpressions(String... emails) {
    return createWithoutPathExpressions(
        Arrays.stream(emails).map(CodeOwnerReference::create).collect(toImmutableSet()));
  }

  @AutoValue.Builder
  public abstract static class Builder {
    /**
     * Sets whether global code owners (code owners from code owner sets without path expression in
     * the same code owner config) and code owners from parent code owner configs (code owner
     * configs in parent folders) should be ignored.
     *
     * @param ignoreGlobalAndParentCodeOwners whether global code owners and code owners from parent
     *     code owner configs should be ignored
     * @return the Builder instance for chaining calls
     * @see CodeOwnerSet#ignoreGlobalAndParentCodeOwners()
     */
    public abstract Builder setIgnoreGlobalAndParentCodeOwners(
        boolean ignoreGlobalAndParentCodeOwners);

    /**
     * Sets that global code owners (code owners from code owner sets without path expression in the
     * same code owner config) and code owners from parent code owner configs (code owner configs in
     * parent folders) should be ignored.
     *
     * @return the Builder instance for chaining calls
     * @see CodeOwnerSet#ignoreGlobalAndParentCodeOwners()
     */
    public Builder setIgnoreGlobalAndParentCodeOwners() {
      return setIgnoreGlobalAndParentCodeOwners(true);
    }

    /**
     * Sets the path expressions that match the files that are owned by the code owners.
     *
     * @param pathExpressions the path expressions
     * @return the Builder instance for chaining calls
     */
    public abstract Builder setPathExpressions(ImmutableSet<String> pathExpressions);

    /** Gets a builder to add path expressions. */
    abstract ImmutableSet.Builder<String> pathExpressionsBuilder();

    /**
     * Adds a path expression.
     *
     * @param pathExpression path expression that should be added
     * @return the Builder instance for chaining calls
     */
    public Builder addPathExpression(String pathExpression) {
      pathExpressionsBuilder().add(requireNonNull(pathExpression, "pathExpression"));
      return this;
    }

    /**
     * Sets the imports of this code owner set.
     *
     * @param codeOwnerConfigReferences references to the code owner configs that should be imported
     * @return the Builder instance for chaining calls
     */
    public abstract Builder setImports(
        ImmutableSet<CodeOwnerConfigReference> codeOwnerConfigReferences);

    /** Gets a builder to add imports. */
    abstract ImmutableSet.Builder<CodeOwnerConfigReference> importsBuilder();

    /**
     * Adds an import.
     *
     * @param codeOwnerConfigReference reference to the code owner config that should be imported
     * @return the Builder instance for chaining calls
     */
    public Builder addImport(CodeOwnerConfigReference codeOwnerConfigReference) {
      importsBuilder().add(requireNonNull(codeOwnerConfigReference, "codeOwnerConfigReference"));
      return this;
    }

    /**
     * Sets the code owners of this code owner set.
     *
     * @param codeOwners the code owners of this code owner set
     * @return the Builder instance for chaining calls
     */
    public abstract Builder setCodeOwners(ImmutableSet<CodeOwnerReference> codeOwners);

    /** Gets a builder to add code owner references. */
    abstract ImmutableSet.Builder<CodeOwnerReference> codeOwnersBuilder();

    /**
     * Adds a code owner.
     *
     * @param codeOwnerReference reference to the code owner
     * @return the Builder instance for chaining calls
     */
    public Builder addCodeOwner(CodeOwnerReference codeOwnerReference) {
      codeOwnersBuilder().add(requireNonNull(codeOwnerReference, "codeOwnerReference"));
      return this;
    }

    /**
     * Adds a code owner for the given email.
     *
     * @param email email of the code owner
     * @return the Builder instance for chaining calls
     */
    public Builder addCodeOwnerEmail(String email) {
      return addCodeOwner(CodeOwnerReference.create(requireNonNull(email, "codeOwnerEmail")));
    }

    /** Builds the {@link CodeOwnerSet} instance. */
    public CodeOwnerSet build() {
      CodeOwnerSet codeOwnerSet = autoBuild();
      checkState(
          !(codeOwnerSet.ignoreGlobalAndParentCodeOwners()
              && codeOwnerSet.pathExpressions().isEmpty()),
          "ignoreGlobalAndParentCodeOwners = true is not allowed for code owner set without path"
              + " expressions");
      checkState(
          !(!codeOwnerSet.imports().isEmpty() && codeOwnerSet.pathExpressions().isEmpty()),
          "imports are not allowed for code owner set without path expressions");
      checkState(
          codeOwnerSet.imports().stream()
              .allMatch(
                  codeOwnerConfigReference ->
                      CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY.equals(
                          codeOwnerConfigReference.importMode())),
          "imports in code owner set must have have import mode %s",
          CodeOwnerConfigImportMode.GLOBAL_CODE_OWNER_SETS_ONLY.name());
      return codeOwnerSet;
    }

    abstract CodeOwnerSet autoBuild();
  }
}
