/*
 * SPDX-License-Identifier: Apache-2.0
 * Copyright (C) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 */

#include "dotErrorHandler.hpp"

#include "base.h"

#include <map>
#include <sstream>

namespace nsm
{
namespace dot
{

// Static map for DOT reason code to error message
static const std::map<uint16_t, std::string> reasonCodeMap = {
    {DOT_RC_INTERNAL_ERROR, "DOTInternalError"},
    {DOT_RC_STATE_INVALID, "DOTStateInvalid"},
    {DOT_RC_SIGNATURE_VERIFICATION_FAILED, "DOTSignatureVerificationFailed"},
    {DOT_RC_STORAGE_ERROR, "DOTStorageError"},
    {DOT_RC_LOCK_DISABLED, "DOTLockDisabled"},
    {DOT_RC_KEY_MISMATCH, "DOTKeyMismatch"},
    {DOT_RC_INVALID_UNLOCK_TYPE, "DOTInvalidUnlockType"},
    {DOT_RC_INVALID_UNLOCK_METHOD, "DOTInvalidUnlockMethod"},
    {DOT_RC_CRYPTO_ERROR, "DOTCryptoError"},
    {DOT_RC_BLOB_CREATION_FAILED, "DOTBlobCreationFailed"},
    {DOT_RC_INVALID_STATE_FOR_LOCK, "DOTInvalidStateForLock"},
    {DOT_RC_INVALID_STATE_FOR_UNLOCK, "DOTInvalidStateForUnlock"},
    {DOT_RC_INVALID_STATE_FOR_DISABLE, "DOTInvalidStateForDisable"},
    {DOT_RC_INVALID_STATE_FOR_CAK_ROTATE, "DOTInvalidStateForCakRotate"},
    {DOT_RC_INVALID_STATE_FOR_CAK_INSTALL, "DOTInvalidStateForCakInstall"},
    {DOT_RC_NULL_POINTER, "DOTNullPointer"},
    {DOT_RC_FUSE_INCREMENT_FAILED, "DOTFuseIncrementFailed"},
    {DOT_RC_RECOVERY_FAILED, "DOTRecoveryFailed"},
    {DOT_RC_INVALID_COMMAND, "DOTInvalidCommand"},
    {DOT_RC_UNSUPPORTED_COMMAND, "DOTUnsupportedCommand"},
    {DOT_RC_INVALID_LENGTH, "DOTInvalidDataLength"}};

// Static map for NSM completion code to error message
static const std::map<uint8_t, std::string> completionCodeMap = {
    {NSM_ERR_INVALID_DATA, "Invalid data provided for DOT operation"},
    {NSM_ERR_INVALID_DATA_LENGTH, "Invalid data length for DOT operation"},
    {NSM_ERR_NOT_READY, "Device not ready for DOT operation"},
    {NSM_ERR_UNSUPPORTED_COMMAND_CODE, "Unsupported DOT command"}};

// Convert DOT operation enum to human-readable string
static const char* dotOperationToString(nsm_firmware_commands op)
{
    switch (op)
    {
        case NSM_FW_DOT_CAK_INSTALL:
            return "DOT CAK Install";
        case NSM_FW_DOT_CAK_BYPASS:
            return "DOT CAK Bypass";
        case NSM_FW_DOT_CAK_ROTATE:
            return "DOT CAK Rotate";
        case NSM_FW_DOT_LOCK:
            return "DOT Lock";
        case NSM_FW_DOT_UNLOCK_CHALLENGE:
            return "DOT Unlock Challenge";
        case NSM_FW_DOT_UNLOCK:
            return "DOT Unlock";
        case NSM_FW_DOT_GET_INFO:
            return "DOT Get Info";
        case NSM_FW_DOT_GET_STATUS:
            return "DOT Get Status";
        case NSM_FW_DOT_DISABLE:
            return "DOT Disable";
        case NSM_FW_DOT_OVERRIDE:
            return "DOT Override";
        case NSM_FW_DOT_RECOVERY:
            return "DOT Recovery";
        default:
            return "DOT Unknown Operation";
    }
}

std::tuple<uint16_t, std::string>
    formatDotDeviceError(uint8_t cc, uint16_t reasonCode,
                         nsm_firmware_commands operation)
{
    std::string errorMsg;
    const char* opName = dotOperationToString(operation);

    // Look up reason code first (more specific)
    auto reasonIt = reasonCodeMap.find(reasonCode);
    if (reasonIt != reasonCodeMap.end())
    {
        errorMsg = reasonIt->second;
    }
    else
    {
        // Fallback to completion code mapping
        if (cc == NSM_SUCCESS)
        {
            errorMsg = std::string(opName) + " completed successfully.";
        }
        else if (cc == NSM_ERROR)
        {
            errorMsg = "An unexpected internal failure occurred while "
                       "processing the DOT request";
            if (reasonCode != 0)
            {
                errorMsg += ", reason code: " + std::to_string(reasonCode);
            }
        }
        else
        {
            auto ccIt = completionCodeMap.find(cc);
            if (ccIt != completionCodeMap.end())
            {
                errorMsg = ccIt->second;
            }
            else
            {
                errorMsg =
                    std::string(opName) +
                    " failed with completion code: " + std::to_string(cc);
                if (reasonCode != 0)
                {
                    errorMsg += ", reason code: " + std::to_string(reasonCode);
                }
            }
        }
    }

    return std::make_tuple(reasonCode, errorMsg);
}

} // namespace dot
} // namespace nsm
