// 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 java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.ImmutableMap;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.change.AllowedFormats;
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.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;

/** 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 IdentifiedUser user;
  @Inject private AllowedFormats allowedFormats;
  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 (s == PacketLineIn.END) {
        break;
      }
      if (!s.startsWith(argCmd)) {
        throw new Failure(1, "fatal: 'argument' token or flush expected");
      }
      String[] parts = s.substring(argCmd.length()).split("=", 2);
      for (String p : parts) {
        args.add(p);
      }
    }

    try {
      // Parse them into the 'options' field
      CmdLineParser parser = new CmdLineParser(options);
      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");
      }

      // 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");
      }

      // Verify the user has permissions to read the specified tree.
      if (!canRead(treeId)) {
        throw new Failure(5, "fatal: cannot perform upload-archive operation");
      }

      // 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 (Failure f) {
      // Report the error in ERROR sideband channel
      try (SideBandOutputStream sidebandError =
          new SideBandOutputStream(
              SideBandOutputStream.CH_ERROR, SideBandOutputStream.MAX_BUF, out)) {
        sidebandError.write(f.getMessage().getBytes(UTF_8));
        sidebandError.flush();
      }
      throw f;
    } 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.<String, Object>of("level", Integer.valueOf(value));
      }
    }
    return Collections.emptyMap();
  }

  private boolean canRead(ObjectId revId) throws IOException, PermissionBackendException {
    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(state, repo, commit);
      }
    }
  }
}
