// Copyright (C) 2015 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.googlesource.gerrit.plugins.verifystatus;

import static com.google.common.base.Preconditions.checkArgument;

import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.gerrit.common.errors.PermissionDeniedException;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityControl;
import com.google.gerrit.server.change.ChangesCollection;
import com.google.gerrit.server.change.RevisionResource;
import com.google.gerrit.server.change.Revisions;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.sshd.commands.PatchSetParser;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.googlesource.gerrit.plugins.verifystatus.common.VerificationInfo;
import com.googlesource.gerrit.plugins.verifystatus.common.VerifyInput;
import java.io.IOException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RequiresCapability(SaveReportCapability.ID)
@CommandMetaData(name = "save", description = "Save patchset verification data")
public class SaveCommand extends SshCommand {
  private static final Logger log = LoggerFactory.getLogger(SaveCommand.class);

  private final Set<PatchSet> patchSets = new HashSet<>();
  private final String pluginName;
  private final Provider<CurrentUser> userProvider;

  @Inject
  SaveCommand(@PluginName String pluginName, Provider<CurrentUser> userProvider) {
    this.pluginName = pluginName;
    this.userProvider = userProvider;
  }

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

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

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

  @Option(
      name = "--verification",
      aliases = "-v",
      usage = "verification to set the result for",
      metaVar = "VERIFY=OUTCOME")
  void addJob(String token) {
    parseWithEquals(token);
  }

  private void parseWithEquals(String text) {
    log.debug("processing verification: " + text);
    checkArgument(!Strings.isNullOrEmpty(text), "Empty verification data");
    Map<String, String> params = null;
    try {
      params = Splitter.on("|").withKeyValueSeparator("=").split(text);
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException(String.valueOf("Invalid verification parameters"));
    }

    String name = params.get("name");
    checkArgument(name != null, "Verification is missing a name");
    checkArgument(!name.isEmpty(), "Verification is missing a name");
    String value = params.get("value");
    checkArgument(value != null, "Verification is missing a value");
    checkArgument(!value.isEmpty(), "Verification is missing a value");
    String abstain = params.get("abstain");
    String rerun = params.get("rerun");
    VerificationInfo data = new VerificationInfo();
    data.name = name;
    data.value = Short.parseShort(value);
    data.abstain = Boolean.valueOf(abstain);
    data.rerun = Boolean.valueOf(rerun);
    data.url = params.get("url");
    data.reporter = params.get("reporter");
    data.comment = params.get("comment");
    data.category = params.get("category");
    data.duration = params.get("duration");
    jobResult.put(name, data);
  }

  @Inject private PostVerification postVerification;

  @Inject private PatchSetParser psParser;

  @Inject private Revisions revisions;

  @Inject private ChangesCollection changes;

  private Map<String, VerificationInfo> jobResult = Maps.newHashMap();

  @Override
  protected void run() throws UnloggedFailure {
    boolean ok = true;
    try {
      checkPermission();
    } catch (PermissionDeniedException err) {
      throw new UnloggedFailure("fatal: " + err.getMessage());
    }

    for (PatchSet patchSet : patchSets) {
      try {
        verifyOne(patchSet);
      } catch (UnloggedFailure e) {
        ok = false;
        writeError("error: " + e.getMessage() + "\n");
      }
    }

    if (!ok) {
      throw new UnloggedFailure(1, "one or more verifications failed;" + " review output above");
    }
  }

  private void applyVerification(PatchSet patchSet, VerifyInput verify)
      throws RestApiException, OrmException, IOException {
    RevisionResource revResource =
        revisions.parse(
            changes.parse(patchSet.getId().getParentKey()),
            IdString.fromUrl(patchSet.getId().getId()));
    postVerification.apply(revResource, verify);
  }

  private void verifyOne(PatchSet patchSet) throws UnloggedFailure {
    VerifyInput verify = new VerifyInput();
    verify.verifications = jobResult;
    try {
      applyVerification(patchSet, verify);
    } catch (RestApiException | OrmException | IOException e) {
      throw PatchSetParser.error(e.getMessage());
    }
  }

  private void writeError(String msg) {
    try {
      err.write(msg.getBytes(ENC));
    } catch (IOException e) {
    }
  }

  /**
   * Assert that the current user is permitted to perform saving of verification reports.
   *
   * <p>As the @RequireCapability guards at various entry points of internal commands implicitly add
   * administrators (which we want to avoid), we also check permissions within QueryShell and grant
   * access only to those who canPerformRawQuery, regardless of whether they are administrators or
   * not.
   *
   * @throws PermissionDeniedException
   */
  private void checkPermission() throws PermissionDeniedException {
    CapabilityControl ctl = userProvider.get().getCapabilities();
    if (!ctl.canPerform(pluginName + "-" + SaveReportCapability.ID)) {
      throw new PermissionDeniedException(
          String.format(
              "%s does not have \"%s\" capability.",
              userProvider.get().getUserName(), new SaveReportCapability().getDescription()));
    }
  }
}
