// Copyright (C) 2009 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.server.submit;

import static java.util.stream.Collectors.toSet;

import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.inject.Provider;
import java.util.List;
import java.util.Optional;

/**
 * Status codes set on {@link com.google.gerrit.server.git.CodeReviewCommit}s by {@link
 * SubmitStrategy} implementations.
 */
public enum CommitMergeStatus {
  CLEAN_MERGE("Change has been successfully merged"),

  CLEAN_PICK("Change has been successfully cherry-picked"),

  CLEAN_REBASE("Change has been successfully rebased and submitted"),

  ALREADY_MERGED(""),

  PATH_CONFLICT(
      "Change could not be merged due to a path conflict.\n"
          + "\n"
          + "Please rebase the change locally and upload the rebased commit for review."),

  REBASE_MERGE_CONFLICT(
      "Change could not be merged due to a conflict.\n"
          + "\n"
          + "Please rebase the change locally and upload the rebased commit for review."),

  SKIPPED_IDENTICAL_TREE(
      "Marking change merged without cherry-picking to branch, as the resulting commit would be"
          + " empty."),

  MISSING_DEPENDENCY("Depends on commit that cannot be merged."),

  MANUAL_RECURSIVE_MERGE(
      "The change requires a local merge to resolve.\n"
          + "\n"
          + "Please merge (or rebase) the change locally and upload the resolution for review."),

  CANNOT_CHERRY_PICK_ROOT(
      "Cannot cherry-pick an initial commit onto an existing branch.\n"
          + "\n"
          + "Please merge the change locally and upload the merge commit for review."),

  CANNOT_REBASE_ROOT(
      "Cannot rebase an initial commit onto an existing branch.\n"
          + "\n"
          + "Please merge the change locally and upload the merge commit for review."),

  NOT_FAST_FORWARD(
      "Project policy requires all submissions to be a fast-forward.\n"
          + "\n"
          + "Please rebase the change locally and upload again for review."),

  EMPTY_COMMIT(
      "Change could not be merged because the commit is empty.\n"
          + "\n"
          + "Project policy requires all commits to contain modifications to at least one file."),

  FAST_FORWARD_INDEPENDENT_CHANGES(
      "Change could not be merged because the submission has two independent changes "
          + "with the same destination branch.\n"
          + "\n"
          + "Independent changes can't be submitted to the same destination branch with "
          + "FAST_FORWARD_ONLY submit strategy");

  private final String description;

  CommitMergeStatus(String description) {
    this.description = description;
  }

  public String getDescription() {
    return description;
  }

  public static String createMissingDependencyMessage(
      @Nullable CurrentUser caller,
      Provider<InternalChangeQuery> queryProvider,
      String commit,
      String otherCommit) {
    List<ChangeData> changes = queryProvider.get().enforceVisibility(true).byCommit(otherCommit);

    if (changes.isEmpty()) {
      return String.format(
          "Commit %s depends on commit %s which cannot be merged."
              + " Is the change of this commit not visible to '%s' or was it deleted?",
          commit, otherCommit, caller != null ? caller.getLoggableName() : "<user-not-available>");
    } else if (changes.size() == 1) {
      ChangeData cd = changes.get(0);
      if (cd.currentPatchSet().commitId().name().equals(otherCommit)) {
        return String.format(
            "Commit %s depends on commit %s of change %d which cannot be merged.",
            commit, otherCommit, cd.getId().get());
      }
      Optional<PatchSet> patchSet =
          cd.patchSets().stream().filter(ps -> ps.commitId().name().equals(otherCommit)).findAny();
      if (patchSet.isPresent()) {
        return String.format(
            "Commit %s depends on commit %s, which is outdated patch set %d of change %d."
                + " The latest patch set is %d.",
            commit,
            otherCommit,
            patchSet.get().id().get(),
            cd.getId().get(),
            cd.currentPatchSet().id().get());
      }
      // should not happen, fall-back to default message
      return String.format(
          "Commit %s depends on commit %s of change %d which cannot be merged.",
          commit, otherCommit, cd.getId().get());
    } else {
      return String.format(
          "Commit %s depends on commit %s of changes %s which cannot be merged.",
          commit, otherCommit, changes.stream().map(cd -> cd.getId().get()).collect(toSet()));
    }
  }
}
