// 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.auto.value.AutoValue;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Patch;
import com.google.gerrit.plugins.codeowners.JgitPath;
import com.google.gerrit.server.patch.PatchListEntry;
import java.nio.file.Path;
import java.util.Optional;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.ChangeType;

/**
 * A file that was touched in a change.
 *
 * <p>Wrapper around {@link DiffEntry} that provides convenience methods to access data from {@link
 * DiffEntry} and hides data that is not relevant for the code owners plugin.
 */
@AutoValue
public abstract class ChangedFile {
  private static final ImmutableMap<Patch.ChangeType, ChangeType> CHANGE_TYPE =
      Maps.immutableEnumMap(
          new ImmutableMap.Builder<Patch.ChangeType, ChangeType>()
              .put(Patch.ChangeType.ADDED, ChangeType.ADD)
              .put(Patch.ChangeType.MODIFIED, ChangeType.MODIFY)
              .put(Patch.ChangeType.DELETED, ChangeType.DELETE)
              .put(Patch.ChangeType.RENAMED, ChangeType.RENAME)
              .put(Patch.ChangeType.COPIED, ChangeType.COPY)
              .put(Patch.ChangeType.REWRITE, ChangeType.MODIFY)
              .build());

  /**
   * The new path of the file.
   *
   * <p>Not set if the file was deleted.
   *
   * <p>If set, the new path is returned as absolute path.
   */
  public abstract Optional<Path> newPath();

  /**
   * The old path of the file.
   *
   * <p>Not set if the file was newly added
   *
   * <p>If set, the old path is returned as absolute path.
   */
  public abstract Optional<Path> oldPath();

  /** Gets the change type. */
  public abstract ChangeType changeType();

  /**
   * Whether the file has the given path as new path.
   *
   * @param absolutePath an absolute path for which it should be checked if it matches the new path
   *     of this file
   */
  public boolean hasNewPath(Path absolutePath) {
    requireNonNull(absolutePath, "absolutePath");
    checkState(absolutePath.isAbsolute(), "path %s must be absolute", absolutePath);
    return newPath().isPresent() && newPath().get().equals(absolutePath);
  }

  /**
   * Whether the file has the given path as old path.
   *
   * @param absolutePath an absolute path for which it should be checked if it matches the old path
   *     of this file
   */
  public boolean hasOldPath(Path absolutePath) {
    requireNonNull(absolutePath, "absolutePath");
    checkState(absolutePath.isAbsolute(), "path %s must be absolute", absolutePath);
    return oldPath().isPresent() && oldPath().get().equals(absolutePath);
  }

  /** Whether the file was renamed. */
  public boolean isRename() {
    return changeType() == ChangeType.RENAME;
  }

  /** Whether the file was deleted. */
  public boolean isDeletion() {
    return changeType() == ChangeType.DELETE;
  }

  /**
   * Creates a {@link ChangedFile} instance from a {@link DiffEntry}.
   *
   * @param diffEntry the diff entry
   */
  public static ChangedFile create(DiffEntry diffEntry) {
    requireNonNull(diffEntry, "diffEntry");
    return new AutoValue_ChangedFile(
        convertPathFromDiffEntryPath(diffEntry.getNewPath()),
        convertPathFromDiffEntryPath(diffEntry.getOldPath()),
        diffEntry.getChangeType());
  }

  /**
   * Converts the given string path to an absolute path.
   *
   * <p>{@link DiffEntry} is using {@code /dev/null} if a path doesn't exist. If the given path is
   * {@code /dev/null} {@link Optional#empty} is returned.
   */
  private static Optional<Path> convertPathFromDiffEntryPath(String path) {
    if (DiffEntry.DEV_NULL.equals(path)) {
      return Optional.empty();
    }
    return Optional.of(JgitPath.of(path).getAsAbsolutePath());
  }

  /**
   * Creates a {@link ChangedFile} instance from a {@link PatchListEntry}.
   *
   * @param patchListEntry the patch list entry
   */
  public static ChangedFile create(PatchListEntry patchListEntry) {
    requireNonNull(patchListEntry, "patchListEntry");

    if (patchListEntry.getChangeType() == Patch.ChangeType.DELETED) {
      // For deletions PatchListEntry sets the old path as new name and the old name is unset (see
      // PatchListEntry constructor). This means to get the old path we need to read the new name.
      return new AutoValue_ChangedFile(
          Optional.empty(),
          convertPathFromPatchListEntry(patchListEntry.getNewName()),
          CHANGE_TYPE.get(patchListEntry.getChangeType()));
    }

    return new AutoValue_ChangedFile(
        convertPathFromPatchListEntry(patchListEntry.getNewName()),
        convertPathFromPatchListEntry(patchListEntry.getOldName()),
        CHANGE_TYPE.get(patchListEntry.getChangeType()));
  }

  /**
   * Converts the given string path to an absolute path.
   *
   * <p>{@link PatchListEntry} is using {@code null} if a path doesn't exist. If the given path is
   * {@code null} {@link Optional#empty} is returned.
   */
  private static Optional<Path> convertPathFromPatchListEntry(@Nullable String path) {
    return Optional.ofNullable(path).map(newName -> JgitPath.of(newName).getAsAbsolutePath());
  }
}
