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

  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 RestApiException {
    gApi.changes()
        .id(patchSet.id().changeId().get())
        .revision(patchSet.commitId().name())
        .review(review);
  }

  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;
    }
  }
}
