// 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.ArchiveFormatInternal;
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();

      ArchiveFormatInternal 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(ArchiveFormatInternal f) {
    if (f == ArchiveFormatInternal.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);
      }
    }
  }
}
