// 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 java.util.Objects.requireNonNull;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.gerrit.plugins.codeowners.JgitPath;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.git.meta.VersionedMetaData;
import java.io.IOException;
import java.util.Optional;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;

/**
 * A representation of a code owner config that is stored as an {@code OWNERS} file in a source
 * branch.
 *
 * <p>For reading code owner configs or creating/updating them, refer to {@link #load(String,
 * CodeOwnerConfigParser, RevWalk, ObjectId, CodeOwnerConfig.Key)} and {@link #loadCurrent(String,
 * CodeOwnerConfigParser, Repository, CodeOwnerConfig.Key)}.
 *
 * <p><strong>Note:</strong> Any modification (code owner config creation or update) only becomes
 * permanent (and hence written to repository) if {@link
 * #commit(com.google.gerrit.server.git.meta.MetaDataUpdate)} is called.
 */
@VisibleForTesting
public class CodeOwnerConfigFile extends VersionedMetaData {
  /**
   * Creates a {@link CodeOwnerConfigFile} for a code owner config.
   *
   * <p>The code owner config is automatically loaded within this method and can be accessed via
   * {@link #getLoadedCodeOwnerConfig()}.
   *
   * <p>It's safe to call this method for non-existing code owner configs. In that case, {@link
   * #getLoadedCodeOwnerConfig()} won't return any code owner config. Thus, the existence of a code
   * owner config can be easily tested.
   *
   * <p>The code owner config represented by the returned {@link CodeOwnerConfigFile} can be
   * created/updated by setting an {@link CodeOwnerConfigUpdate} via {@link
   * #setCodeOwnerConfigUpdate(CodeOwnerConfigUpdate)} and committing the {@link
   * CodeOwnerConfigUpdate} via {@link #commit(com.google.gerrit.server.git.meta.MetaDataUpdate)}.
   *
   * @param defaultFileName the name of the code owner configuration files that should be used if
   *     none is specified in the code owner config key
   * @param codeOwnerConfigParser the parser that should be used to parse code owner config files
   * @param revWalk the revWalk that should be used to load the revision
   * @param revision the branch revision from which the code owner config file should be loaded
   * @param codeOwnerConfigKey the key of the code owner config
   * @return a {@link CodeOwnerConfigFile} for the code owner config with the specified key
   * @throws IOException if the repository can't be accessed for some reason
   * @throws ConfigInvalidException if the code owner config exists but can't be read due to an
   *     invalid format
   */
  public static CodeOwnerConfigFile load(
      String defaultFileName,
      CodeOwnerConfigParser codeOwnerConfigParser,
      RevWalk revWalk,
      ObjectId revision,
      CodeOwnerConfig.Key codeOwnerConfigKey)
      throws IOException, ConfigInvalidException {
    requireNonNull(defaultFileName, "defaultFileName");
    requireNonNull(codeOwnerConfigParser, "codeOwnerConfigParser");
    requireNonNull(revWalk, "revWalk");
    requireNonNull(revision, "revision");
    requireNonNull(codeOwnerConfigKey, "codeOwnerConfigKey");

    CodeOwnerConfigFile codeOwnerConfigFile =
        new CodeOwnerConfigFile(defaultFileName, codeOwnerConfigParser, codeOwnerConfigKey);
    codeOwnerConfigFile.load(codeOwnerConfigKey.project(), revWalk, revision);
    return codeOwnerConfigFile;
  }

  /**
   * Creates a {@link CodeOwnerConfigFile} for a code owner config from the current revision in the
   * branch.
   *
   * @param defaultFileName the name of the code owner configuration files that should be used if
   *     none is specified in the code owner config key
   * @param codeOwnerConfigParser the parser that should be used to parse code owner config files
   * @param repository the repository in which the code owner config is stored
   * @param codeOwnerConfigKey the key of the code owner config
   * @return a {@link CodeOwnerConfigFile} for the code owner config with the specified key
   * @throws IOException if the repository can't be accessed for some reason
   * @throws ConfigInvalidException if the code owner config exists but can't be read due to an
   *     invalid format
   * @see #load(String, CodeOwnerConfigParser, RevWalk, ObjectId, CodeOwnerConfig.Key)
   */
  public static CodeOwnerConfigFile loadCurrent(
      String defaultFileName,
      CodeOwnerConfigParser codeOwnerConfigParser,
      Repository repository,
      CodeOwnerConfig.Key codeOwnerConfigKey)
      throws IOException, ConfigInvalidException {
    requireNonNull(defaultFileName, "defaultFileName");
    requireNonNull(codeOwnerConfigParser, "codeOwnerConfigParser");
    requireNonNull(repository, "repository");
    requireNonNull(codeOwnerConfigKey, "codeOwnerConfigKey");

    CodeOwnerConfigFile codeOwnerConfigFile =
        new CodeOwnerConfigFile(defaultFileName, codeOwnerConfigParser, codeOwnerConfigKey);
    codeOwnerConfigFile.load(codeOwnerConfigKey.project(), repository);
    return codeOwnerConfigFile;
  }

  private final String defaultFileName;
  private final CodeOwnerConfigParser codeOwnerConfigParser;
  private final CodeOwnerConfig.Key codeOwnerConfigKey;

  private boolean isLoaded = false;
  private Optional<CodeOwnerConfig> loadedCodeOwnersConfig = Optional.empty();
  private Optional<CodeOwnerConfigUpdate> codeOwnerConfigUpdate = Optional.empty();

  private CodeOwnerConfigFile(
      String defaultFileName,
      CodeOwnerConfigParser codeOwnerConfigParser,
      CodeOwnerConfig.Key codeOwnerConfigKey) {
    this.defaultFileName = defaultFileName;
    this.codeOwnerConfigParser = codeOwnerConfigParser;
    this.codeOwnerConfigKey = codeOwnerConfigKey;
  }

  /**
   * Returns the loaded code owner config if it exists.
   *
   * @return the loaded code owner config, or {@link Optional#empty()} if the code owner config
   *     doesn't exist
   */
  public Optional<CodeOwnerConfig> getLoadedCodeOwnerConfig() {
    checkLoaded();

    // If a loaded code owner config is present, update its revision if it is outdated.
    if (loadedCodeOwnersConfig.isPresent()
        && (!loadedCodeOwnersConfig.get().revision().equals(revision))) {
      loadedCodeOwnersConfig =
          Optional.of(loadedCodeOwnersConfig.get().toBuilder().setRevision(revision).build());
    }

    return loadedCodeOwnersConfig;
  }

  /**
   * Specifies how the current code owner config should be updated.
   *
   * <p>If the code owner config is newly created, the {@link CodeOwnerConfigUpdate} can be used to
   * specify optional properties.
   *
   * <p>If the update leads to an empty code owner config, the code owner config file is deleted.
   *
   * <p><strong>Note:</strong> This method doesn't perform the update. It only contains the
   * instructions for the update. To apply the update for real, call {@link
   * #commit(com.google.gerrit.server.git.meta.MetaDataUpdate)} on this {@link CodeOwnerConfigFile}.
   *
   * @param codeOwnerConfigUpdate an {@code CodeOwnerConfigUpdate} outlining the modifications which
   *     should be applied
   * @return this {@code CodeOwnerConfigFile} instance to allow chaining calls
   */
  public CodeOwnerConfigFile setCodeOwnerConfigUpdate(CodeOwnerConfigUpdate codeOwnerConfigUpdate) {
    this.codeOwnerConfigUpdate = Optional.of(codeOwnerConfigUpdate);
    return this;
  }

  @Override
  protected String getRefName() {
    return codeOwnerConfigKey.branchNameKey().branch();
  }

  @Override
  protected void onLoad() throws IOException, ConfigInvalidException {
    if (revision != null) {
      Optional<String> codeOwnerConfigFileContent =
          getFileIfItExists(JgitPath.of(codeOwnerConfigKey.filePath(defaultFileName)).get());
      if (codeOwnerConfigFileContent.isPresent()) {
        try {
          loadedCodeOwnersConfig =
              Optional.of(
                  codeOwnerConfigParser.parse(
                      revision, codeOwnerConfigKey, codeOwnerConfigFileContent.get()));
        } catch (CodeOwnerConfigParseException e) {
          throw new ConfigInvalidException(e.getFullMessage(defaultFileName), e);
        }
      }
    }

    isLoaded = true;
  }

  /**
   * Loads the file with the given path and returns the file content if the file exists.
   *
   * @param filePath the path of the file that should be loaded
   * @return the content of the file if it exists, otherwise {@link Optional#empty()}.
   */
  private Optional<String> getFileIfItExists(String filePath) throws IOException {
    try (TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), filePath, revision.getTree())) {
      if (tw != null) {
        return Optional.of(readUTF8(filePath));
      }
    }
    return Optional.empty();
  }

  @Override
  public RevCommit commit(MetaDataUpdate update) throws IOException {
    // Reject the creation of a code owner config if the branch doesn't exist.
    checkState(
        update.getRepository().exactRef(getRefName()) != null,
        "branch %s does not exist",
        getRefName());

    return super.commit(update);
  }

  @Override
  protected boolean onSave(CommitBuilder commit) throws IOException, ConfigInvalidException {
    checkLoaded();

    if (!codeOwnerConfigUpdate.isPresent()) {
      // Code owner config was neither created nor changed. -> A new commit isn't necessary.
      return false;
    }

    // Update the code owner config.
    CodeOwnerConfig originalCodeOwnerConfig =
        loadedCodeOwnersConfig.orElse(
            CodeOwnerConfig.builder(codeOwnerConfigKey, revision).build());
    CodeOwnerConfig updatedCodeOwnerConfig =
        updateCodeOwnerConfig(originalCodeOwnerConfig, codeOwnerConfigUpdate.get());

    // Do not create a new commit if the code owner config didn't change.
    if (updatedCodeOwnerConfig.equals(originalCodeOwnerConfig)) {
      return false;
    }

    // Compute the new content of the code owner config file.
    String codeOwnerConfigFileContent =
        codeOwnerConfigParser.formatAsString(updatedCodeOwnerConfig);

    // Save the new code owner config.
    saveUTF8(
        JgitPath.of(codeOwnerConfigKey.filePath(defaultFileName)).get(),
        codeOwnerConfigFileContent);

    // If the file content is empty, the update led to a deletion of the code owner config file.
    boolean isDeleted = codeOwnerConfigFileContent.isEmpty();

    // Set a commit message if none was set yet.
    if (Strings.isNullOrEmpty(commit.getMessage())) {
      commit.setMessage(
          String.format(
              "%s code owner config",
              loadedCodeOwnersConfig.isPresent() ? (isDeleted ? "Delete" : "Update") : "Create"));
    }

    loadedCodeOwnersConfig = isDeleted ? Optional.empty() : Optional.of(updatedCodeOwnerConfig);
    codeOwnerConfigUpdate = Optional.empty();

    return true;
  }

  private static CodeOwnerConfig updateCodeOwnerConfig(
      CodeOwnerConfig codeOwnerConfig, CodeOwnerConfigUpdate codeOwnerConfigUpdate) {
    CodeOwnerConfig.Builder codeOwnerConfigBuilder = codeOwnerConfig.toBuilder();
    codeOwnerConfigUpdate
        .ignoreParentCodeOwners()
        .ifPresent(codeOwnerConfigBuilder::setIgnoreParentCodeOwners);
    codeOwnerConfigBuilder.setCodeOwnerSets(
        codeOwnerConfigUpdate
            .codeOwnerSetsModification()
            .apply(codeOwnerConfig.codeOwnerSetsAsList()));
    codeOwnerConfigBuilder.setImports(
        codeOwnerConfigUpdate.importsModification().apply(codeOwnerConfig.importsAsList()));
    return codeOwnerConfigBuilder.build();
  }

  private void checkLoaded() {
    checkState(isLoaded, "Code owner config %s not loaded yet", codeOwnerConfigKey);
  }
}
