/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *    Copyright (c) 2013-2017 Nest Labs, 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.
 */

/**
 *    @file
 *      This file implements the command handler for the 'chip-cert' tool
 *      that prints the contents of a CHIP certificate.
 *
 */

#include "chip-cert.h"

namespace {

using namespace chip;
using namespace chip::ArgParser;
using namespace chip::Credentials;
using namespace chip::ASN1;

#define CMD_NAME "chip-cert print-cert"

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg);
bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[]);

// clang-format off
OptionDef gCmdOptionDefs[] =
{
    { "out",           kArgumentRequired, 'o' },
    { }
};

const char * const gCmdOptionHelp =
    "   -o, --out <file/stdout>\n"
    "\n"
    "       The output printed certificate file name. If not specified\n"
    "       or if specified '-' then output is written to stdout.\n"
    "\n"
    ;

OptionSet gCmdOptions =
{
    HandleOption,
    gCmdOptionDefs,
    "COMMAND OPTIONS",
    gCmdOptionHelp
};

HelpOptions gHelpOptions(
    CMD_NAME,
    "Usage: " CMD_NAME " [<options...>] <file/str>\n",
    CHIP_VERSION_STRING "\n" COPYRIGHT_STRING,
    "Print a CHIP operational certificate.\n"
    "\n"
    "ARGUMENTS\n"
    "\n"
    "  <file/str>\n"
    "\n"
    "       File or string containing a CHIP certificate.\n"
    "\n"
);

OptionSet *gCmdOptionSets[] =
{
    &gCmdOptions,
    &gHelpOptions,
    nullptr
};
// clang-format on

const char * gInFileNameOrStr = nullptr;
const char * gOutFileName     = "-";

bool HandleOption(const char * progName, OptionSet * optSet, int id, const char * name, const char * arg)
{
    switch (id)
    {
    case 'o':
        gOutFileName = arg;
        break;
    default:
        PrintArgError("%s: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

bool HandleNonOptionArgs(const char * progName, int argc, char * const argv[])
{
    if (argc == 0)
    {
        PrintArgError("%s: Please specify the name of the certificate to be printed.\n", progName);
        return false;
    }

    if (argc > 1)
    {
        PrintArgError("%s: Unexpected argument: %s\n", progName, argv[1]);
        return false;
    }

    gInFileNameOrStr = argv[0];

    return true;
}

void Indent(FILE * file, int count)
{
    while (count--)
    {
        fputc(' ', file);
    }
}

void PrintHexField(FILE * file, const char * name, int indent, size_t count, const uint8_t * data, size_t countPerRow = 16)
{
    Indent(file, indent);
    indent += fprintf(file, "%s: ", name);

    for (size_t i = 0; i < count; i++)
    {
        if (i != 0 && i != count && i % countPerRow == 0)
        {
            fprintf(file, "\n");
            Indent(file, indent);
        }

        fprintf(file, "%02X ", data[i]);
    }

    fprintf(file, "\n");
}

void PrintEpochTime(FILE * file, const char * name, int indent, uint32_t epochTime)
{
    chip::ASN1::ASN1UniversalTime asn1Time;

    ChipEpochToASN1Time(epochTime, asn1Time);

    Indent(file, indent);
    fprintf(file, "%s: ", name);

    fprintf(file, "0x%08" PRIX32 "  ( %04d/%02d/%02d %02d:%02d:%02d )\n", epochTime, asn1Time.Year, asn1Time.Month, asn1Time.Day,
            asn1Time.Hour, asn1Time.Minute, asn1Time.Second);
}

void PrintDN(FILE * file, const char * name, int indent, const ChipDN * dn)
{
    uint8_t rdnCount = dn->RDNCount();
    char valueStr[128];

    Indent(file, indent);
    indent += fprintf(file, "%s: [[ ", name);

    for (uint8_t i = 0; i < rdnCount; i++)
    {
        if (IsChip64bitDNAttr(dn->rdn[i].mAttrOID))
        {
            snprintf(valueStr, sizeof(valueStr), "%016" PRIX64, dn->rdn[i].mChipVal);
        }
        else if (IsChip32bitDNAttr(dn->rdn[i].mAttrOID))
        {
            snprintf(valueStr, sizeof(valueStr), "%08" PRIX32, static_cast<uint32_t>(dn->rdn[i].mChipVal));
        }
        else
        {
            size_t len = dn->rdn[i].mString.size();
            if (len > sizeof(valueStr) - 1)
            {
                len = sizeof(valueStr) - 1;
            }
            memcpy(valueStr, dn->rdn[i].mString.data(), len);
            valueStr[len] = 0;
        }

        fprintf(file, "%s = %s", chip::ASN1::GetOIDName(dn->rdn[i].mAttrOID), valueStr);
        if (i == rdnCount - 1)
        {
            fprintf(file, " ]]\n");
        }
        else
        {
            fprintf(file, ",\n");
            Indent(file, indent);
        }
    }
}

bool PrintCert(const char * fileName, X509 * cert)
{
    bool res       = true;
    CHIP_ERROR err = CHIP_NO_ERROR;
    FILE * file    = nullptr;
    ChipCertificateSet certSet;
    const ChipCertificateData * certData;
    chip::BitFlags<CertDecodeFlags> decodeFlags;
    uint8_t chipCertBuf[kMaxCHIPCertLength];
    MutableByteSpan chipCert(chipCertBuf);
    int indent = 4;

    VerifyOrExit(cert != nullptr, res = false);

    res = OpenFile(fileName, file, true);
    VerifyTrueOrExit(res);

    res = X509ToChipCert(cert, chipCert);
    VerifyTrueOrExit(res);

    err = certSet.Init(1);
    if (err != CHIP_NO_ERROR)
    {
        fprintf(stderr, "Failed to initialize certificate set: %s\n", chip::ErrorStr(err));
        ExitNow(res = false);
    }

    err = certSet.LoadCert(chipCert, decodeFlags);
    if (err != CHIP_NO_ERROR)
    {
        fprintf(stderr, "Error reading %s: %s\n", fileName, chip::ErrorStr(err));
        ExitNow(res = false);
    }

    certData = certSet.GetLastCert();

    fprintf(file, "CHIP Certificate:\n");

    Indent(file, indent);
    fprintf(file, "Signature Algo  : %s\n", GetOIDName(certData->mSigAlgoOID));

    PrintDN(file, "Issuer          ", indent, &certData->mIssuerDN);

    PrintEpochTime(file, "Not Before      ", indent, certData->mNotBeforeTime);

    PrintEpochTime(file, "Not After       ", indent, certData->mNotAfterTime);

    PrintDN(file, "Subject         ", indent, &certData->mSubjectDN);

    Indent(file, indent);
    fprintf(file, "Public Key Algo : %s\n", GetOIDName(certData->mPubKeyAlgoOID));

    Indent(file, indent);
    fprintf(file, "Curve Id        : %s\n", GetOIDName(certData->mPubKeyCurveOID));

    PrintHexField(file, "Public Key      ", indent, certData->mPublicKey.size(), certData->mPublicKey.data());

    Indent(file, indent);
    fprintf(file, "Extensions:\n");

    indent += 4;
    Indent(file, indent);
    fprintf(file, "Is CA            : %s\n", certData->mCertFlags.Has(CertFlags::kIsCA) ? "true" : "false");

    if (certData->mCertFlags.Has(CertFlags::kPathLenConstraintPresent))
    {
        Indent(file, indent);
        fprintf(file, "Path Length Const: %u\n", (unsigned) certData->mPathLenConstraint);
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_KeyUsage))
    {
        Indent(file, indent);
        fprintf(file, "Key Usage        : ");
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kDigitalSignature))
        {
            fprintf(file, "DigitalSignature ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kNonRepudiation))
        {
            fprintf(file, "NonRepudiation ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kKeyEncipherment))
        {
            fprintf(file, "KeyEncipherment ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kDataEncipherment))
        {
            fprintf(file, "DataEncipherment ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kKeyAgreement))
        {
            fprintf(file, "KeyAgreement ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kKeyCertSign))
        {
            fprintf(file, "KeyCertSign ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kCRLSign))
        {
            fprintf(file, "CRLSign ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kEncipherOnly))
        {
            fprintf(file, "EncipherOnly ");
        }
        if (certData->mKeyUsageFlags.Has(KeyUsageFlags::kDecipherOnly))
        {
            fprintf(file, "DecipherOnly ");
        }
        fprintf(file, "\n");
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_ExtendedKeyUsage))
    {
        Indent(file, indent);
        fprintf(file, "Key Purpose      : ");
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kServerAuth))
        {
            fprintf(file, "ServerAuth ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kClientAuth))
        {
            fprintf(file, "ClientAuth ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kCodeSigning))
        {
            fprintf(file, "CodeSigning ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kEmailProtection))
        {
            fprintf(file, "EmailProtection ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kTimeStamping))
        {
            fprintf(file, "TimeStamping ");
        }
        if (certData->mKeyPurposeFlags.Has(KeyPurposeFlags::kOCSPSigning))
        {
            fprintf(file, "OCSPSigning ");
        }
        fprintf(file, "\n");
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_SubjectKeyId))
    {
        PrintHexField(file, "Subject Key Id   ", indent, certData->mSubjectKeyId.size(), certData->mSubjectKeyId.data(),
                      certData->mSubjectKeyId.size());
    }

    if (certData->mCertFlags.Has(CertFlags::kExtPresent_AuthKeyId))
    {
        PrintHexField(file, "Authority Key Id ", indent, certData->mAuthKeyId.size(), certData->mAuthKeyId.data(),
                      certData->mAuthKeyId.size());
    }

    indent -= 4;
    PrintHexField(file, "Signature       ", indent, certData->mSignature.size(), certData->mSignature.data());

exit:
    CloseFile(file);
    return res;
}

} // namespace

bool Cmd_PrintCert(int argc, char * argv[])
{
    bool res = true;
    std::unique_ptr<X509, void (*)(X509 *)> cert(X509_new(), &X509_free);

    if (argc == 1)
    {
        gHelpOptions.PrintBriefUsage(stderr);
        ExitNow(res = true);
    }

    res = ParseArgs(CMD_NAME, argc, argv, gCmdOptionSets, HandleNonOptionArgs);
    VerifyTrueOrExit(res);

    res = ReadCert(gInFileNameOrStr, cert.get());
    VerifyTrueOrExit(res);

    res = PrintCert(gOutFileName, cert.get());
    VerifyTrueOrExit(res);

exit:
    return res;
}
