
// CheckSum.java
// From https://picocli.info/#_introduction
// Modified by Andrew Davison, ad@coe.psu.ac.th, June 2023

/*
  Usage: CheckSum [-hV] [-a=<alg>] <file>
  Prints a file's checksum.
      <file>              The file whose checksum is calculated.
  -a, --algorithm=<alg>   SHA-1, SHA-256, MD5, ...  (default: SHA-1)
  -h, --help              Show this help message and exit.
  -V, --version           Print version information and exit.


  Picocli features:
    * named options and positional parameters
    * POSIX-style grouped short options 
    * automatic help and version options
    * default values
    * exit codes
    * conversion of command line arguments to data types


  Usage examples:
   > compile CheckSum.java

    > run CheckSum -h
    > run CheckSum -V
    > run CheckSum CheckSum.java
*/


import java.io.*;
import java.math.*;
import java.nio.file.*;
import java.security.*;
import java.util.concurrent.*;

import picocli.CommandLine;
import picocli.CommandLine.*;


@Command(name = "CheckSum", 
         mixinStandardHelpOptions = true,
         version = "CheckSum 4.0",
         description = "Prints a file's checksum.")
public class CheckSum implements Callable<Integer>
{

  @Parameters(index = "0",
              description = "The file whose checksum is calculated.")
  private File file;   // converted from String

  @Option(names = {"-a", "--algorithm"},
          description = "SHA-1, SHA-256, MD5, ...  (default: ${DEFAULT-VALUE})")
  private String alg = "SHA-1";  // default value


  public Integer call()
  {
    try {
      byte[] bytes = Files.readAllBytes(file.toPath());
      byte[] digest = MessageDigest.getInstance(alg).digest(bytes);
      System.out.printf("%0" + (digest.length*2) + "x%n",
                                 new BigInteger(1, digest));
      return 0;
    }
    catch (Exception e) {
      System.err.println(e.getMessage());
      return 1;
    }
  } /* call */


  // --------------------------------------

  public static void main(String[] args)
  {
    int exitCode = new CommandLine(new CheckSum()).execute(args);
    System.exit(exitCode);
  }


}  // end of CheckSum class
