// Copyright (C) 2014 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.server.project.ProjectCache.illegalState;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.change.ArchiveFormat;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.restapi.change.AllowedFormats;
import com.google.gerrit.server.restapi.project.CommitsCollection;
import com.google.gerrit.sshd.AbstractGitCommand;
import com.google.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.api.ArchiveCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.PacketLineIn;
import org.eclipse.jgit.transport.PacketLineOut;
import org.eclipse.jgit.transport.SideBandOutputStream;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.ParserProperties;

/** Allows getting archives for Git repositories over SSH using the Git upload-archive protocol. */
public class UploadArchive extends AbstractGitCommand {
  /**
   * Options for parsing Git commands.
   *
   * <p>These options are not passed on command line, but received through input stream in pkt-line
   * format.
   */
  static class Options {
    @Option(
        name = "-f",
        aliases = {"--format"},
        usage =
            "Format of the"
                + " resulting archive: tar or zip... If this option is not given, and"
                + " the output file is specified, the format is inferred from the"
                + " filename if possible (e.g. writing to \"foo.zip\" makes the output"
                + " to be in the zip format). Otherwise the output format is tar.")
    private String format = "tar";

    @Option(name = "--prefix", usage = "Prepend <prefix>/ to each filename in the archive.")
    private String prefix;

    @Option(name = "-0", usage = "Store the files instead of deflating them.")
    private boolean level0;

    @Option(name = "-1")
    private boolean level1;

    @Option(name = "-2")
    private boolean level2;

    @Option(name = "-3")
    private boolean level3;

    @Option(name = "-4")
    private boolean level4;

    @Option(name = "-5")
    private boolean level5;

    @Option(name = "-6")
    private boolean level6;

    @Option(name = "-7")
    private boolean level7;

    @Option(name = "-8")
    private boolean level8;

    @Option(
        name = "-9",
        usage =
            "Highest and slowest compression level. You "
                + "can specify any number from 1 to 9 to adjust compression speed and "
                + "ratio.")
    private boolean level9;

    @Argument(index = 0, required = true, usage = "The tree or commit to produce an archive for.")
    private String treeIsh = "master";

    @Argument(
        index = 1,
        multiValued = true,
        usage =
            "Without an optional path parameter, all files and subdirectories of "
                + "the current working directory are included in the archive. If one "
                + "or more paths are specified, only these are included.")
    private List<String> path;
  }

  @Inject private PermissionBackend permissionBackend;
  @Inject private CommitsCollection commits;
  @Inject private AllowedFormats allowedFormats;
  @Inject private ProjectCache projectCache;
  private Options options = new Options();

  /**
   * Read and parse arguments from input stream. This method gets the arguments from input stream,
   * in Pkt-line format, then parses them to fill the options object.
   */
  protected void readArguments() throws IOException, Failure {
    String argCmd = "argument ";
    List<String> args = new ArrayList<>();

    // Read arguments in Pkt-Line format
    PacketLineIn packetIn = new PacketLineIn(in);
    for (; ; ) {
      String s = packetIn.readString();
      if (PacketLineIn.isEnd(s)) {
        break;
      }
      if (!s.startsWith(argCmd)) {
        throw new Failure(1, "fatal: 'argument' token or flush expected, got " + s);
      }
      for (String p : Splitter.on('=').limit(2).split(s.substring(argCmd.length()))) {
        args.add(p);
      }
    }

    try {
      // Parse them into the 'options' field
      CmdLineParser parser =
          new CmdLineParser(options, ParserProperties.defaults().withAtSyntax(false));
      parser.parseArgument(args);
      if (options.path == null || Arrays.asList(".").equals(options.path)) {
        options.path = Collections.emptyList();
      }
    } catch (CmdLineException e) {
      throw new Failure(2, "fatal: unable to parse arguments, " + e);
    }
  }

  @Override
  protected void runImpl() throws IOException, PermissionBackendException, Failure {
    PacketLineOut packetOut = new PacketLineOut(out);
    packetOut.setFlushOnEnd(true);
    packetOut.writeString("ACK");
    packetOut.end();

    try {
      // Parse Git arguments
      readArguments();

      ArchiveFormat f = allowedFormats.getExtensions().get("." + options.format);
      if (f == null) {
        throw new Failure(3, "fatal: upload-archive not permitted for format " + options.format);
      }

      // Find out the object to get from the specified reference and paths
      ObjectId treeId = repo.resolve(options.treeIsh);
      if (treeId == null) {
        throw new Failure(4, "fatal: reference not found: " + options.treeIsh);
      }

      // Verify the user has permissions to read the specified tree.
      if (!canRead(treeId)) {
        throw new Failure(5, "fatal: no permission to read tree" + options.treeIsh);
      }

      // The archive is sent in DATA sideband channel
      try (SideBandOutputStream sidebandOut =
          new SideBandOutputStream(
              SideBandOutputStream.CH_DATA, SideBandOutputStream.MAX_BUF, out)) {
        new ArchiveCommand(repo)
            .setFormat(f.name())
            .setFormatOptions(getFormatOptions(f))
            .setTree(treeId)
            .setPaths(options.path.toArray(new String[0]))
            .setPrefix(options.prefix)
            .setOutputStream(sidebandOut)
            .call();
        sidebandOut.flush();
      } catch (GitAPIException e) {
        throw new Failure(7, "fatal: git api exception, " + e);
      }
    } catch (Throwable t) {
      // Report the error in ERROR sideband channel. Catch Throwable too so we can also catch
      // NoClassDefFound.
      try (SideBandOutputStream sidebandError =
          new SideBandOutputStream(
              SideBandOutputStream.CH_ERROR, SideBandOutputStream.MAX_BUF, out)) {
        sidebandError.write(t.getMessage().getBytes(UTF_8));
        sidebandError.flush();
      }
      throw t;
    } finally {
      // In any case, cleanly close the packetOut channel
      packetOut.end();
    }
  }

  private Map<String, Object> getFormatOptions(ArchiveFormat f) {
    if (f == ArchiveFormat.ZIP) {
      int value =
          Arrays.asList(
                  options.level0,
                  options.level1,
                  options.level2,
                  options.level3,
                  options.level4,
                  options.level5,
                  options.level6,
                  options.level7,
                  options.level8,
                  options.level9)
              .indexOf(true);
      if (value >= 0) {
        return ImmutableMap.of("level", Integer.valueOf(value));
      }
    }
    return Collections.emptyMap();
  }

  private boolean canRead(ObjectId revId) throws IOException, PermissionBackendException {
    ProjectState projectState =
        projectCache.get(projectName).orElseThrow(illegalState(projectName));

    if (!projectState.statePermitsRead()) {
      return false;
    }

    try {
      permissionBackend.user(user).project(projectName).check(ProjectPermission.READ);
      return true;
    } catch (AuthException e) {
      // Check reachability of the specific revision.
      try (RevWalk rw = new RevWalk(repo)) {
        RevCommit commit = rw.parseCommit(revId);
        return commits.canRead(projectState, repo, commit);
      }
    }
  }
}
