/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "digesttool.h"
#include "argparse.h"
#include "nss_scoped_ptrs.h"
#include "util.h"

#include <algorithm>
#include <fstream>
#include <iomanip>
#include <iostream>

#include <hasht.h>  // contains supported digest types
#include <nss.h>
#include <pk11pub.h>
#include <prio.h>

static SECOidData* HashTypeToOID(HASH_HashType hashtype) {
  SECOidTag hashtag;

  if (hashtype <= HASH_AlgNULL || hashtype >= HASH_AlgTOTAL) {
    return nullptr;
  }

  switch (hashtype) {
    case HASH_AlgMD5:
      hashtag = SEC_OID_MD5;
      break;
    case HASH_AlgSHA1:
      hashtag = SEC_OID_SHA1;
      break;
    case HASH_AlgSHA224:
      hashtag = SEC_OID_SHA224;
      break;
    case HASH_AlgSHA256:
      hashtag = SEC_OID_SHA256;
      break;
    case HASH_AlgSHA384:
      hashtag = SEC_OID_SHA384;
      break;
    case HASH_AlgSHA512:
      hashtag = SEC_OID_SHA512;
      break;
    default:
      return nullptr;
  }

  return SECOID_FindOIDByTag(hashtag);
}

static SECOidData* HashNameToOID(const std::string& hashName) {
  for (size_t htype = HASH_AlgNULL + 1; htype < HASH_AlgTOTAL; htype++) {
    SECOidData* hashOID = HashTypeToOID(static_cast<HASH_HashType>(htype));
    if (hashOID && std::string(hashOID->desc) == hashName) {
      return hashOID;
    }
  }

  return nullptr;
}

static bool Digest(const ArgParser& parser, SECOidData* hashOID);
static bool ComputeDigest(std::istream& is, ScopedPK11Context& hashCtx);

bool DigestTool::Run(const std::vector<std::string>& arguments) {
  ArgParser parser(arguments);

  if (parser.GetPositionalArgumentCount() != 1) {
    Usage();
    return false;
  }

  // no need for a db for the digest tool
  SECStatus rv = NSS_NoDB_Init(".");
  if (rv != SECSuccess) {
    std::cerr << "NSS init failed!" << std::endl;
    return false;
  }

  std::string hashName = parser.GetPositionalArgument(0);
  std::transform(hashName.begin(), hashName.end(), hashName.begin(), ::toupper);
  SECOidData* hashOID = HashNameToOID(hashName);
  if (hashOID == nullptr) {
    std::cerr << "Error: Unknown digest type "
              << parser.GetPositionalArgument(0) << "." << std::endl;
    return false;
  }

  bool ret = Digest(parser, hashOID);

  // shutdown nss
  if (NSS_Shutdown() != SECSuccess) {
    std::cerr << "NSS Shutdown failed!" << std::endl;
    return false;
  }

  return ret;
}

void DigestTool::Usage() {
  std::cerr << "Usage: nss digest md5|sha-1|sha-224|sha-256|sha-384|sha-512 "
               "[--infile <path>]"
            << std::endl;
}

static bool Digest(const ArgParser& parser, SECOidData* hashOID) {
  std::string inputFile;
  if (parser.Has("--infile")) {
    inputFile = parser.Get("--infile");
  }

  ScopedPK11Context hashCtx(PK11_CreateDigestContext(hashOID->offset));
  if (hashCtx == nullptr) {
    std::cerr << "Creating digest context failed." << std::endl;
    return false;
  }
  PK11_DigestBegin(hashCtx.get());

  std::ifstream fis;
  std::istream& is = GetStreamFromFileOrStdin(inputFile, fis);
  if (!is.good() || !ComputeDigest(is, hashCtx)) {
    return false;
  }

  unsigned char digest[HASH_LENGTH_MAX];
  unsigned int len;
  SECStatus rv = PK11_DigestFinal(hashCtx.get(), digest, &len, HASH_LENGTH_MAX);
  if (rv != SECSuccess || len == 0) {
    std::cerr << "Calculating final hash value failed." << std::endl;
    return false;
  }

  // human readable output
  for (size_t i = 0; i < len; i++) {
    std::cout << std::setw(2) << std::setfill('0') << std::hex
              << static_cast<int>(digest[i]);
  }
  std::cout << std::endl;

  return true;
}

static bool ComputeDigest(std::istream& is, ScopedPK11Context& hashCtx) {
  while (is) {
    unsigned char buf[4096];
    is.read(reinterpret_cast<char*>(buf), sizeof(buf));
    if (is.fail() && !is.eof()) {
      std::cerr << "Error reading from input stream." << std::endl;
      return false;
    }
    SECStatus rv = PK11_DigestOp(hashCtx.get(), buf, is.gcount());
    if (rv != SECSuccess) {
      std::cerr << "PK11_DigestOp failed." << std::endl;
      return false;
    }
  }

  return true;
}
