/*
 * Copyright 2017 Google LLC
 *
 * 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.helloworld;

import com.google.crypto.tink.Aead;
import com.google.crypto.tink.CleartextKeysetHandle;
import com.google.crypto.tink.JsonKeysetReader;
import com.google.crypto.tink.JsonKeysetWriter;
import com.google.crypto.tink.KeyTemplates;
import com.google.crypto.tink.KeysetHandle;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
import org.kohsuke.args4j.spi.SubCommand;
import org.kohsuke.args4j.spi.SubCommandHandler;
import org.kohsuke.args4j.spi.SubCommands;

/** Defines the different sub-commands and their parameters, for command-line invocation. */
public final class Commands {
  /** An interface for a command-line sub-command. */
  interface Command {
    public void run() throws Exception;
  }

  static class Options {
    @Option(
      name = "--keyset",
      required = true,
      usage = "The path to the keyset, generate new if does not exist"
    )
    File keyset;

    @Option(name = "--in", required = true, usage = "The input filename")
    File inFile;

    @Option(name = "--out", required = true, usage = "The output filename")
    File outFile;
  }

  /** Loads a KeysetHandle from {@code keyset} or generate a new one if it doesn't exist. */
  private static KeysetHandle getKeysetHandle(File keyset)
      throws GeneralSecurityException, IOException {
    if (keyset.exists()) {
      // Read the cleartext keyset from disk.
      // WARNING: reading cleartext keysets is a bad practice. Tink supports reading/writing
      // encrypted keysets, see
      // https://github.com/google/tink/blob/master/docs/JAVA-HOWTO.md#loading-existing-keysets.
      return CleartextKeysetHandle.read(JsonKeysetReader.withFile(keyset));
    }
    KeysetHandle handle = KeysetHandle.generateNew(KeyTemplates.get("AES128_GCM"));
    CleartextKeysetHandle.write(handle, JsonKeysetWriter.withFile(keyset));
    return handle;
  }

  /**
   * Encrypts a file.
   */
  public static class EncryptCommand extends Options implements Command {
    @Override
    public void run() throws Exception {
      // 1. Obtain a keyset handle.
      KeysetHandle handle = getKeysetHandle(keyset);
      // 2. Get a primitive.
      Aead aead = handle.getPrimitive(Aead.class);
      // 3. Do crypto. It's that simple!
      byte[] plaintext = Files.readAllBytes(inFile.toPath());
      byte[] ciphertext = aead.encrypt(plaintext, new byte[0] /* associatedData */);
      try (FileOutputStream stream = new FileOutputStream(outFile)) {
        stream.write(ciphertext);
      }
    }
  }

  /**
   * Decrypts a file.
   */
  public static class DecryptCommand extends Options implements Command {
    @Override
    public void run() throws Exception {
      KeysetHandle handle = getKeysetHandle(keyset);
      Aead aead = handle.getPrimitive(Aead.class);
      byte[] ciphertext = Files.readAllBytes(inFile.toPath());
      byte[] plaintext = aead.decrypt(ciphertext, new byte[0] /* associatedData */);
      try (FileOutputStream stream = new FileOutputStream(outFile)) {
        stream.write(plaintext);
      }
    }
  }

  @Argument(
    metaVar = "command",
    required = true,
    handler = SubCommandHandler.class,
    usage = "The subcommand to run"
  )
  @SubCommands({
    @SubCommand(name = "encrypt", impl = EncryptCommand.class),
    @SubCommand(name = "decrypt", impl = DecryptCommand.class)
  })
  Command command;
}
