/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (c) 2013-2014,  Regents of the University of California.
 * All rights reserved.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * This file licensed under New BSD License.  See COPYING for detailed information about
 * ndn-cxx library copyright, permissions, and redistribution restrictions.
 *
 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
 */

#ifndef NDNSEC_DSK_GEN_HPP
#define NDNSEC_DSK_GEN_HPP

#include "ndnsec-util.hpp"

int
ndnsec_dsk_gen(int argc, char** argv)
{
  using namespace ndn;
  namespace po = boost::program_options;

  std::string identityName;
  char keyType = 'r';
  int keySize = 2048;

  po::options_description description("General Usage\n  ndnsec dsk-gen [-h] identity\nGeneral options");
  description.add_options()
    ("help,h", "produce help message")
    ("identity,i", po::value<std::string>(&identityName), "identity name, for example, /ndn/ucla.edu/alice")
    // ("type,t", po::value<char>(&keyType)->default_value('r'), "optional, key type, r for RSA key (default)")
    // ("size,s", po::value<int>(&keySize)->default_value(2048), "optional, key size, 2048 (default)")
    ;

  po::positional_options_description p;
  p.add("identity", 1);

  po::variables_map vm;
  try
    {
      po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(),
                vm);
      po::notify(vm);
    }
  catch (const std::exception& e)
    {
      std::cerr << "ERROR: " << e.what() << std::endl;
      std::cerr << description << std::endl;
      return 1;
    }

  if (vm.count("help") != 0)
    {
      std::cerr << description << std::endl;
      return 0;
    }

  if (vm.count("identity") == 0)
    {
      std::cerr << "identity must be specified" << std::endl;
      std::cerr << description << std::endl;
      return 1;
    }

  shared_ptr<IdentityCertificate> kskCert;
  Name signingCertName;

  KeyChain keyChain;

  Name defaultCertName = keyChain.getDefaultCertificateNameForIdentity(identityName);
  bool isDefaultDsk = false;
  if (defaultCertName.get(-3).toUri().substr(0,4) == "dsk-")
    isDefaultDsk = true;

  if (isDefaultDsk)
    {
      shared_ptr<IdentityCertificate> dskCert = keyChain.getCertificate(defaultCertName);
      SignatureSha256WithRsa sha256sig(dskCert->getSignature());

      Name keyLocatorName = sha256sig.getKeyLocator().getName(); // will throw exception if keylocator is absent or it is not a name

      Name kskName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
      Name kskCertName = keyChain.getDefaultCertificateNameForKey(kskName);
      signingCertName = kskCertName;
      kskCert = keyChain.getCertificate(kskCertName);
    }
  else
    {
      signingCertName = defaultCertName;
      kskCert = keyChain.getCertificate(defaultCertName);
    }

  if (!static_cast<bool>(kskCert))
    {
      std::cerr << "ERROR: no KSK certificate." << std::endl;
      return 1;
    }

  Name newKeyName;
  switch (keyType)
    {
    case 'r':
      {
        newKeyName = keyChain.generateRsaKeyPair(Name(identityName), false, keySize);
        if (0 == newKeyName.size())
          {
            std::cerr << "fail to generate key!" << std::endl;
            return 1;
          }
        break;
      }
    default:
      std::cerr << "Unrecongized key type" << "\n";
      std::cerr << description << std::endl;
      return 1;
    }

  Name certName = newKeyName.getPrefix(-1);
  certName.append("KEY")
    .append(newKeyName.get(-1))
    .append("ID-CERT")
    .appendVersion();

  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
  certificate->setName(certName);
  certificate->setNotBefore(kskCert->getNotBefore());
  certificate->setNotAfter(kskCert->getNotAfter());

  certificate->setPublicKeyInfo(*keyChain.getPublicKey(newKeyName));

  const std::vector<CertificateSubjectDescription>& subList =
    kskCert->getSubjectDescriptionList();

  for (std::vector<CertificateSubjectDescription>::const_iterator it = subList.begin();
       it != subList.end(); it++)
    certificate->addSubjectDescription(*it);

  certificate->encode();

  keyChain.sign(*certificate, signingCertName);

  keyChain.addCertificateAsIdentityDefault(*certificate);

  return 0;
}

#endif //NDNSEC_DSK_GEN_HPP
