// Copyright 2016 Google Inc. All rights reserved.
//
// 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.archivepatcher.tools;

import com.google.archivepatcher.applier.FileByFileV1DeltaApplier;
import com.google.archivepatcher.generator.DeltaFriendlyOldBlobSizeLimiter;
import com.google.archivepatcher.generator.FileByFileV1DeltaGenerator;
import com.google.archivepatcher.generator.RecommendationModifier;
import com.google.archivepatcher.generator.TotalRecompressionLimiter;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Simple command-line tool for generating and applying patches.
 */
public class FileByFileTool extends AbstractTool {

  /** Usage instructions for the command line. */
  private static final String USAGE =
      "java -cp <classpath> com.google.archivepatcher.tools.FileByFileTool <options>\n"
          + "\nOptions:\n"
          + "  --generate      generate a patch\n"
          + "  --apply         apply a patch\n"
          + "  --old           the old file\n"
          + "  --new           the new file\n"
          + "  --patch         the patch file\n"
          + "  --trl           optionally, the total bytes of recompression to allow (see below)\n"
          + "  --dfobsl        optionally, a limit on the total size of the delta-friendly old blob (see below)\n"
          + "\nTotal Recompression Limit (trl):\n"
          + "  When generating a patch, a limit can be specified on the total number of bytes to\n"
          + "  allow to be recompressed during the patch apply process. This can be for a variety\n"
          + "  of reasons, with the most obvious being to limit the amount of effort that has to\n"
          + "  be expended applying the patch on the target platform. To properly explain a\n"
          + "  patch that had such a limitation, it is necessary to specify the same limitation\n"
          + "  here. This argument is illegal for --apply, since it only applies to --generate.\n"
          + "\nDelta Friendly Old Blob Size Limit (dfobsl):\n"
          + "  When generating a patch, a limit can be specified on the total size of the delta-\n"
          + "  friendly old blob. This implicitly limits the size of the temporary file that\n"
          + "  needs to be created when applying the patch. The size limit is \"soft\" in that \n"
          + "  the delta-friendly old blob needs to at least contain the original data that was\n"
          + "  within it; but the limit specified here will constrain any attempt to uncompress\n"
          + "  the content. If the limit is less than or equal to the size of the old file, no\n"
          + "  uncompression will be performed at all. Otherwise, the old file can expand into\n"
          + "  delta-friendly old blob until the size reaches this limit.\n"
          + "\nExamples:\n"
          + "  To generate a patch from OLD to NEW, saving the patch in PATCH:\n"
          + "    java -cp <classpath> com.google.archivepatcher.tools.FileByFileTool --generate \\\n"
          + "      --old OLD --new NEW --patch PATCH\n"
          + "  To generate a patch from OLD to NEW, limiting to 1,000,000 recompress bytes:\n"
          + "    java -cp <classpath> com.google.archivepatcher.tools.FileByFileTool --generate \\\n"
          + "      --old OLD --new NEW --trl 1000000 --patch PATCH\n"
          + "  To apply a patch PATCH to OLD, saving the result in NEW:\n"
          + "    java -cp <classpath> com.google.archivepatcher.tools.FileByFileTool --apply \\\n"
          + "      --old OLD --patch PATCH --new NEW";

  /**
   * Modes of operation.
   */
  private static enum Mode {
    /**
     * Generate a patch.
     */
    GENERATE,

    /**
     * Apply a patch.
     */
    APPLY;
  }

  /**
   * Runs the tool. See usage instructions for more information.
   *
   * @param args command line arguments
   * @throws IOException if anything goes wrong
   * @throws InterruptedException if any thread has interrupted the current thread
   */
  public static void main(String... args) throws IOException, InterruptedException {
    new FileByFileTool().run(args);
  }

  /**
   * Run the tool.
   *
   * @param args command line arguments
   * @throws IOException if anything goes wrong
   * @throws InterruptedException if any thread has interrupted the current thread
   */
  public void run(String... args) throws IOException, InterruptedException {
    String oldPath = null;
    String newPath = null;
    String patchPath = null;
    Long totalRecompressionLimit = null;
    Long deltaFriendlyOldBlobSizeLimit = null;
    Mode mode = null;
    Iterator<String> argIterator = new LinkedList<String>(Arrays.asList(args)).iterator();
    while (argIterator.hasNext()) {
      String arg = argIterator.next();
      if ("--old".equals(arg)) {
        oldPath = popOrDie(argIterator, "--old");
      } else if ("--new".equals(arg)) {
        newPath = popOrDie(argIterator, "--new");
      } else if ("--patch".equals(arg)) {
        patchPath = popOrDie(argIterator, "--patch");
      } else if ("--generate".equals(arg)) {
        mode = Mode.GENERATE;
      } else if ("--apply".equals(arg)) {
        mode = Mode.APPLY;
      } else if ("--trl".equals(arg)) {
        totalRecompressionLimit = Long.parseLong(popOrDie(argIterator, "--trl"));
        if (totalRecompressionLimit < 0) {
          exitWithUsage("--trl cannot be negative: " + totalRecompressionLimit);
        }
      } else if ("--dfobsl".equals(arg)) {
        deltaFriendlyOldBlobSizeLimit = Long.parseLong(popOrDie(argIterator, "--dfobsl"));
        if (deltaFriendlyOldBlobSizeLimit < 0) {
          exitWithUsage("--dfobsl cannot be negative: " + deltaFriendlyOldBlobSizeLimit);
        }
      } else {
        exitWithUsage("unknown argument: " + arg);
      }
    }
    if (oldPath == null || newPath == null || patchPath == null || mode == null) {
      exitWithUsage("missing required argument(s)");
    }
    if (mode == Mode.APPLY && totalRecompressionLimit != null) {
      exitWithUsage("--trl can only be used with --generate");
    }
    if (mode == Mode.APPLY && deltaFriendlyOldBlobSizeLimit != null) {
      exitWithUsage("--dfobsl can only be used with --generate");
    }
    File oldFile = getRequiredFileOrDie(oldPath, "old file");
    if (mode == Mode.GENERATE) {
      File newFile = getRequiredFileOrDie(newPath, "new file");
      generatePatch(
          oldFile,
          newFile,
          new File(patchPath),
          totalRecompressionLimit,
          deltaFriendlyOldBlobSizeLimit);
    } else { // mode == Mode.APPLY
      File patchFile = getRequiredFileOrDie(patchPath, "patch file");
      applyPatch(oldFile, patchFile, new File(newPath));
    }
  }

  /**
   * Generate a specified patch to transform the specified old file to the specified new file.
   *
   * @param oldFile the old file (will be read)
   * @param newFile the new file (will be read)
   * @param patchFile the patch file (will be written)
   * @param totalRecompressionLimit optional limit for total number of bytes of recompression to
   *     allow in the resulting patch
   * @param deltaFriendlyOldBlobSizeLimit optional limit for the size of the delta-friendly old
   *     blob, which implies a limit on the temporary space needed to apply the generated patch
   * @throws IOException if anything goes wrong
   * @throws InterruptedException if any thread has interrupted the current thread
   */
  public static void generatePatch(
      File oldFile,
      File newFile,
      File patchFile,
      Long totalRecompressionLimit,
      Long deltaFriendlyOldBlobSizeLimit)
      throws IOException, InterruptedException {
    List<RecommendationModifier> recommendationModifiers = new ArrayList<RecommendationModifier>();
    if (totalRecompressionLimit != null) {
      recommendationModifiers.add(new TotalRecompressionLimiter(totalRecompressionLimit));
    }
    if (deltaFriendlyOldBlobSizeLimit != null) {
      recommendationModifiers.add(
          new DeltaFriendlyOldBlobSizeLimiter(deltaFriendlyOldBlobSizeLimit));
    }
    FileByFileV1DeltaGenerator generator =
        new FileByFileV1DeltaGenerator(
            recommendationModifiers.toArray(new RecommendationModifier[] {}));
    try (FileOutputStream patchOut = new FileOutputStream(patchFile);
        BufferedOutputStream bufferedPatchOut = new BufferedOutputStream(patchOut)) {
      generator.generateDelta(oldFile, newFile, bufferedPatchOut);
      bufferedPatchOut.flush();
    }
  }

  /**
   * Apply a specified patch to the specified old file, creating the specified new file.
   * @param oldFile the old file (will be read)
   * @param patchFile the patch file (will be read)
   * @param newFile the new file (will be written)
   * @throws IOException if anything goes wrong
   */
  public static void applyPatch(File oldFile, File patchFile, File newFile) throws IOException {
    // Figure out temp directory
    File tempFile = File.createTempFile("fbftool", "tmp");
    File tempDir = tempFile.getParentFile();
    tempFile.delete();
    FileByFileV1DeltaApplier applier = new FileByFileV1DeltaApplier(tempDir);
    try (FileInputStream patchIn = new FileInputStream(patchFile);
        BufferedInputStream bufferedPatchIn = new BufferedInputStream(patchIn);
        FileOutputStream newOut = new FileOutputStream(newFile);
        BufferedOutputStream bufferedNewOut = new BufferedOutputStream(newOut)) {
      applier.applyDelta(oldFile, bufferedPatchIn, bufferedNewOut);
      bufferedNewOut.flush();
    }
  }

  @Override
  protected String getUsage() {
    return USAGE;
  }
}
