// 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.sshd.commands;

import static com.google.gerrit.util.cli.Localizable.localizable;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.common.io.CharStreams;
import com.google.gerrit.entities.LabelType;
import com.google.gerrit.entities.LabelValue;
import com.google.gerrit.entities.PatchSet;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.AbandonInput;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.MoveInput;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
import com.google.gerrit.extensions.api.changes.RestoreInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.json.OutputFormat;
import com.google.gerrit.server.DynamicOptions;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.update.RetryableAction.ActionType;
import com.google.gerrit.server.util.LabelVote;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.util.cli.CmdLineParser;
import com.google.gerrit.util.cli.OptionUtil;
import com.google.gson.JsonSyntaxException;
import com.google.inject.Inject;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.AnnotatedElement;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.OptionDef;
import org.kohsuke.args4j.spi.FieldSetter;
import org.kohsuke.args4j.spi.OneArgumentOptionHandler;
import org.kohsuke.args4j.spi.Setter;

@CommandMetaData(name = "review", description = "Apply reviews to one or more patch sets")
public class ReviewCommand extends SshCommand {
  private static final FluentLogger logger = FluentLogger.forEnclosingClass();

  @Override
  protected final CmdLineParser newCmdLineParser(Object options) {
    CmdLineParser parser = super.newCmdLineParser(options);
    optionMap.forEach((o, s) -> parser.addOption(s, o));
    return parser;
  }

  private final Set<PatchSet> patchSets = new HashSet<>();

  @Argument(
      index = 0,
      required = true,
      multiValued = true,
      metaVar = "{COMMIT | CHANGE,PATCHSET}",
      usage = "list of commits or patch sets to review")
  void addPatchSetId(String token) {
    try {
      PatchSet ps = psParser.parsePatchSet(token, projectState, branch);
      patchSets.add(ps);
    } catch (UnloggedFailure e) {
      throw new IllegalArgumentException(e.getMessage(), e);
    } catch (StorageException e) {
      throw new IllegalArgumentException("database error", e);
    }
  }

  @Option(
      name = "--project",
      aliases = "-p",
      usage = "project containing the specified patch set(s)")
  private ProjectState projectState;

  @Option(name = "--branch", aliases = "-b", usage = "branch containing the specified patch set(s)")
  private String branch;

  @Option(
      name = "--message",
      aliases = "-m",
      usage = "cover message to publish on change(s)",
      metaVar = "MESSAGE")
  private String changeComment;

  @Option(
      name = "--notify",
      aliases = "-n",
      usage = "Who to send email notifications to after the review is stored.",
      metaVar = "NOTIFYHANDLING")
  private NotifyHandling notify;

  @Option(name = "--abandon", usage = "abandon the specified change(s)")
  private boolean abandonChange;

  @Option(name = "--restore", usage = "restore the specified abandoned change(s)")
  private boolean restoreChange;

  @Option(name = "--rebase", usage = "rebase the specified change(s)")
  private boolean rebaseChange;

  @Option(name = "--move", usage = "move the specified change(s)", metaVar = "BRANCH")
  private String moveToBranch;

  @Option(name = "--submit", aliases = "-s", usage = "submit the specified patch set(s)")
  private boolean submitChange;

  @Option(name = "--json", aliases = "-j", usage = "read review input json from stdin")
  private boolean json;

  @Option(
      name = "--tag",
      aliases = "-t",
      usage = "applies a tag to the given review",
      metaVar = "TAG")
  private String changeTag;

  @Option(
      name = "--label",
      aliases = "-l",
      usage = "custom label(s) to assign",
      metaVar = "LABEL=VALUE")
  void addLabel(String token) {
    LabelVote v = LabelVote.parseWithEquals(token);
    LabelType.checkName(v.label()); // Disallow SUBM.
    customLabels.put(v.label(), v.value());
  }

  @Inject private ProjectCache projectCache;

  @Inject private AllProjectsName allProjects;

  @Inject private GerritApi gApi;

  @Inject private PatchSetParser psParser;

  @Inject private RetryHelper retryHelper;

  private Map<Option, LabelSetter> optionMap;
  private Map<String, Short> customLabels;

  @Override
  protected void run() throws UnloggedFailure {
    enableGracefulStop();
    if (abandonChange) {
      if (restoreChange) {
        throw die("abandon and restore actions are mutually exclusive");
      }
      if (submitChange) {
        throw die("abandon and submit actions are mutually exclusive");
      }
      if (rebaseChange) {
        throw die("abandon and rebase actions are mutually exclusive");
      }
      if (moveToBranch != null) {
        throw die("abandon and move actions are mutually exclusive");
      }
    }
    if (json) {
      if (restoreChange) {
        throw die("json and restore actions are mutually exclusive");
      }
      if (submitChange) {
        throw die("json and submit actions are mutually exclusive");
      }
      if (abandonChange) {
        throw die("json and abandon actions are mutually exclusive");
      }
      if (changeComment != null) {
        throw die("json and message are mutually exclusive");
      }
      if (rebaseChange) {
        throw die("json and rebase actions are mutually exclusive");
      }
      if (moveToBranch != null) {
        throw die("json and move actions are mutually exclusive");
      }
      if (changeTag != null) {
        throw die("json and tag actions are mutually exclusive");
      }
    }
    if (rebaseChange) {
      if (submitChange) {
        throw die("rebase and submit actions are mutually exclusive");
      }
    }

    boolean ok = true;
    ReviewInput input = null;
    if (json) {
      input = reviewFromJson();
    }

    for (PatchSet patchSet : patchSets) {
      try {
        if (input != null) {
          applyReview(patchSet, input);
        } else {
          reviewPatchSet(patchSet);
        }
      } catch (RestApiException | UnloggedFailure e) {
        ok = false;
        writeError("error", e.getMessage() + "\n");
      } catch (NoSuchChangeException e) {
        ok = false;
        writeError("error", "no such change " + patchSet.id().changeId().get());
      } catch (Exception e) {
        ok = false;
        writeError("fatal", "internal server error while reviewing " + patchSet.id() + "\n");
        logger.atSevere().withCause(e).log("internal error while reviewing %s", patchSet.id());
      }
    }

    if (!ok) {
      throw die("one or more reviews failed; review output above");
    }
  }

  private void applyReview(PatchSet patchSet, ReviewInput review) throws Exception {
    retryHelper
        .action(
            ActionType.CHANGE_UPDATE,
            "applyReview",
            () -> {
              gApi.changes()
                  .id(patchSet.id().changeId().get())
                  .revision(patchSet.commitId().name())
                  .review(review);
              return null;
            })
        .call();
  }

  private ReviewInput reviewFromJson() throws UnloggedFailure {
    try (InputStreamReader r = new InputStreamReader(in, UTF_8)) {
      return OutputFormat.JSON.newGson().fromJson(CharStreams.toString(r), ReviewInput.class);
    } catch (IOException | JsonSyntaxException e) {
      writeError("error", e.getMessage() + '\n');
      throw die("internal error while reading review input");
    }
  }

  private void reviewPatchSet(PatchSet patchSet) throws Exception {

    ReviewInput review = new ReviewInput();
    review.message = Strings.emptyToNull(changeComment);
    review.tag = Strings.emptyToNull(changeTag);
    review.notify = notify;
    review.labels = new TreeMap<>();
    review.drafts = ReviewInput.DraftHandling.PUBLISH;
    for (LabelSetter setter : optionMap.values()) {
      setter.getValue().ifPresent(v -> review.labels.put(setter.getLabelName(), v));
    }
    review.labels.putAll(customLabels);

    // We don't need to add the review comment when abandoning/restoring.
    if (abandonChange || restoreChange || moveToBranch != null) {
      review.message = null;
    }

    try {
      if (abandonChange) {
        AbandonInput input = new AbandonInput();
        input.message = Strings.emptyToNull(changeComment);
        applyReview(patchSet, review);
        changeApi(patchSet).abandon(input);
      } else if (restoreChange) {
        RestoreInput input = new RestoreInput();
        input.message = Strings.emptyToNull(changeComment);
        changeApi(patchSet).restore(input);
        applyReview(patchSet, review);
      } else {
        applyReview(patchSet, review);
      }

      if (moveToBranch != null) {
        MoveInput moveInput = new MoveInput();
        moveInput.destinationBranch = moveToBranch;
        moveInput.message = Strings.emptyToNull(changeComment);
        changeApi(patchSet).move(moveInput);
      }

      if (rebaseChange) {
        revisionApi(patchSet).rebase();
      }

      if (submitChange) {
        revisionApi(patchSet).submit();
      }

    } catch (IllegalStateException | RestApiException e) {
      throw die(e);
    }
  }

  private ChangeApi changeApi(PatchSet patchSet) throws RestApiException {
    return gApi.changes().id(patchSet.id().changeId().get());
  }

  private RevisionApi revisionApi(PatchSet patchSet) throws RestApiException {
    return changeApi(patchSet).revision(patchSet.commitId().name());
  }

  @Override
  protected void parseCommandLine(DynamicOptions pluginOptions) throws UnloggedFailure {
    optionMap = new LinkedHashMap<>();
    customLabels = new HashMap<>();

    ProjectState allProjectsState;
    try {
      allProjectsState = projectCache.getAllProjects();
    } catch (Exception e) {
      throw die("missing " + allProjects.get(), e);
    }

    for (LabelType type : allProjectsState.getLabelTypes().getLabelTypes()) {
      StringBuilder usage = new StringBuilder("score for ").append(type.getName()).append("\n");

      for (LabelValue v : type.getValues()) {
        usage.append(v.format()).append("\n");
      }

      optionMap.put(newApproveOption(type, usage.toString()), new LabelSetter(type));
    }

    super.parseCommandLine(pluginOptions);
  }

  private static String asOptionName(LabelType type) {
    return "--" + type.getName().toLowerCase();
  }

  private static Option newApproveOption(LabelType type, String usage) {
    return OptionUtil.newOption(
        asOptionName(type),
        ImmutableList.of(),
        usage,
        "N",
        false,
        false,
        false,
        LabelHandler.class,
        ImmutableList.of(),
        ImmutableList.of());
  }

  private static class LabelSetter implements Setter<Short> {
    private final LabelType type;
    private Optional<Short> value;

    LabelSetter(LabelType type) {
      this.type = requireNonNull(type);
      this.value = Optional.empty();
    }

    Optional<Short> getValue() {
      return value;
    }

    LabelType getLabelType() {
      return type;
    }

    String getLabelName() {
      return type.getName();
    }

    @Override
    public void addValue(Short value) {
      this.value = Optional.of(value);
    }

    @Override
    public Class<Short> getType() {
      return Short.class;
    }

    @Override
    public boolean isMultiValued() {
      return false;
    }

    @Override
    public FieldSetter asFieldSetter() {
      throw new UnsupportedOperationException();
    }

    @Override
    public AnnotatedElement asAnnotatedElement() {
      throw new UnsupportedOperationException();
    }
  }

  public static class LabelHandler extends OneArgumentOptionHandler<Short> {
    private final LabelType type;

    public LabelHandler(
        org.kohsuke.args4j.CmdLineParser parser, OptionDef option, Setter<Short> setter) {
      super(parser, option, setter);
      this.type = ((LabelSetter) setter).getLabelType();
    }

    @Override
    protected Short parse(String token) throws NumberFormatException, CmdLineException {
      String argument = token;
      if (argument.startsWith("+")) {
        argument = argument.substring(1);
      }

      short value = Short.parseShort(argument);
      LabelValue min = type.getMin();
      LabelValue max = type.getMax();

      if (value < min.getValue() || value > max.getValue()) {
        String e =
            "\""
                + token
                + "\" must be in range "
                + min.formatValue()
                + ".."
                + max.formatValue()
                + " for \""
                + asOptionName(type)
                + "\"";
        throw new CmdLineException(owner, localizable(e));
      }
      return value;
    }
  }
}
