// Copyright 2024 Google LLC
//
// 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.

#include "ec_util.hpp"

#include "google3/host_commands.h"

#include "host_command.hpp"
#include "message_util.hpp"
#include "payload_update.hpp"

#include <stdplus/print.hpp>
#include <stdplus/raw.hpp>
#include <xyz/openbmc_project/Control/Hoth/error.hpp>

#include <algorithm>
#include <array>
#include <cstdint>
#include <span>
#include <vector>

namespace google
{
namespace hoth
{
namespace internal
{
using sdbusplus::error::xyz::openbmc_project::control::hoth::ResponseFailure;

namespace
{
constexpr std::string_view kPanicDataMagic = "Pnc!";
constexpr uint32_t kPanicDataSize = 144;

bool matchPersistentPanicMagic(std::span<const uint8_t> response_body)
{
    if (response_body.size() < kPanicDataSize)
    {
        return false;
    }

    return (response_body[kPanicDataSize - 4] == kPanicDataMagic[0] &&
            response_body[kPanicDataSize - 3] == kPanicDataMagic[1] &&
            response_body[kPanicDataSize - 2] == kPanicDataMagic[2] &&
            response_body[kPanicDataSize - 1] == kPanicDataMagic[3]);
}

} // namespace

[[nodiscard]] std::vector<uint8_t> EcUtilImpl::sendCommand(
    uint16_t command, uint8_t* request_ptr, size_t request_size) const
{
    std::vector<uint8_t> response_bytes =
        hostCmd->sendCommand(command, kVersionZero, request_ptr, request_size);
    std::span<uint8_t> response = response_bytes;
    auto& rsp = stdplus::raw::extractRef<RspHeader>(response);
    if (rsp.result != EC_RES_SUCCESS)
    {
        throw CommandRunException(command, rsp.result);
    }
    return {response.begin(), response.end()};
}

bool EcUtilImpl::isHostCommandSupported(uint16_t cmd) const
{
    ec_request_is_host_command_supported req = {.command = cmd};

    try
    {
        std::vector<uint8_t> response_body =
            sendCommand(EC_CMD_BOARD_SPECIFIC_BASE +
                            EC_PRV_CMD_HOTH_IS_HOST_COMMAND_SUPPORTED,
                        reinterpret_cast<uint8_t*>(&req), sizeof(req));

        ec_response_is_host_command_supported response_struct =
            stdplus::raw::copyFrom<ec_response_is_host_command_supported>(
                response_body);

        return response_struct.is_allowed != 0;
    }
    catch (const std::exception& e)
    {
        stdplus::print(stderr,
                       "Failed to query host command support for {:#x}: {}\n",
                       cmd, e.what());
        return false;
    }
}

ec_response_statistics EcUtilImpl::getHothStatistics() const
{
    std::vector<uint8_t> response_body =
        sendCommand(EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_GET_STATISTICS,
                    /*request_ptr=*/nullptr, /*request_size=*/0);
    return stdplus::raw::copyFrom<ec_response_statistics>(response_body);
}

std::variant<ec_response_chip_info, std::array<uint8_t, kOtDeviceIdLenInBytes>>
    EcUtilImpl::getHothChipInfo() const
{
    std::vector<uint8_t> response_body =
        sendCommand(EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_CHIP_INFO,
                    /*request_ptr=*/nullptr, /*request_size=*/0);
    // Based on logic in
    // [libhoth](https://github.com/google/libhoth/blob/6607098671ff84d4994b8feff202acc679d15434/protocol/chipinfo.c#L39-L53)
    if (response_body.size() == kOtDeviceIdLenInBytes)
    {
        std::array<uint8_t, kOtDeviceIdLenInBytes> device_id_bytes;
        std::copy_n(response_body.begin(), kOtDeviceIdLenInBytes,
                    device_id_bytes.begin());
        return device_id_bytes;
    }
    if (response_body.size() == sizeof(ec_response_chip_info))
    {
        return stdplus::raw::copyFromStrict<ec_response_chip_info>(
            response_body);
    }
    stdplus::print(stderr, "Bad response length for chipinfo {}\n",
                   response_body.size());
    throw ResponseFailure();
}

bool EcUtilImpl::checkHothPersistentPanicInfo() const
{
    ec_request_persistent_panic_info req = {
        .operation = PERSISTENT_PANIC_INFO_GET,
        .index = 0,
    };

    std::vector<uint8_t> response_body = sendCommand(
        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PERSISTENT_PANIC_INFO,
        reinterpret_cast<uint8_t*>(&req), sizeof(req));
    const size_t chunk_size = HOTH_PERSISTENT_PANIC_INFO_CHUNK_SIZE;
    if (response_body.size() != chunk_size)
    {
        stdplus::print(stderr, "Bad response length {} (expected {})\n",
                       response_body.size(), chunk_size);
        throw ResponseFailure();
    }

    return matchPersistentPanicMagic(response_body);
}

ec_authz_record_get_response EcUtilImpl::getHothAuthRecord() const
{
    const uint16_t kGetAuthRecordCmd =
        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_GET_AUTHZ_RECORD;

    if (!isHostCommandSupported(kGetAuthRecordCmd))
    {
        throw CommandNotSupportedException(kGetAuthRecordCmd);
    }

    ec_authz_record_get_request request = {
        .index = 0,
        .reserved = {},
    };

    std::vector<uint8_t> response_body =
        sendCommand(kGetAuthRecordCmd, reinterpret_cast<uint8_t*>(&request),
                    sizeof(request));
    return stdplus::raw::copyFrom<ec_authz_record_get_response>(response_body);
}

ec_response_key_rotation_status EcUtilImpl::getHothKeyRotationStatus() const
{
    const uint16_t keyRotationCommand =
        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_KEY_ROTATION_OP;
    if (!isHostCommandSupported(keyRotationCommand))
    {
        throw CommandNotSupportedException(keyRotationCommand);
    }

    ec_request_key_rotation_record request = {
        .operation = KEY_ROTATION_RECORD_GET_STATUS,
        .packet_offset = 0,
        .packet_size = 0,
        .reserved = 0,
    };

    std::vector<uint8_t> response_body =
        sendCommand(keyRotationCommand, reinterpret_cast<uint8_t*>(&request),
                    sizeof(request));
    return stdplus::raw::copyFrom<ec_response_key_rotation_status>(
        response_body);
}

secure_boot_enforcement_state EcUtilImpl::getSecureBootEnforcementState() const
{
    const uint16_t kGetSecureBootEnforcementState =
        EC_CMD_BOARD_SPECIFIC_BASE +
        EC_PRV_CMD_HOTH_GET_SECURE_BOOT_ENFORCEMENT;

    if (!isHostCommandSupported(kGetSecureBootEnforcementState))
    {
        throw CommandNotSupportedException(kGetSecureBootEnforcementState);
    }

    std::vector<uint8_t> response_body =
        sendCommand(kGetSecureBootEnforcementState,
                    /*request_ptr=*/nullptr, /*request_size=*/0);
    return stdplus::raw::copyFrom<secure_boot_enforcement_state>(response_body);
}

void EcUtilImpl::setTpmLocality(uint8_t locality) const
{
    ec_request_tpm_control request = {
        .version = 0,
        .operation = TPM_CONTROL_SET_LOCALITY,
        .payload_size = sizeof(uint8_t),
        .locality = locality,
    };

    std::vector<uint8_t> response_body =
        sendCommand(EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_TPM_CONTROL,
                    reinterpret_cast<uint8_t*>(&request), sizeof(request));

    if (!response_body.empty())
    {
        stdplus::print(
            stderr, "Unexpected host command response size. Want 0; Got {}\n",
            response_body.size());
        throw ResponseFailure();
    }
}

uint8_t EcUtilImpl::getTpmLocality() const
{
    ec_request_tpm_control request = {
        .version = 0,
        .operation = TPM_CONTROL_GET_LOCALITY,
        .payload_size = 0,
        .locality = 0, // field not used, but keep for compiler erros.
    };
    std::vector<uint8_t> response_body =
        sendCommand(EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_TPM_CONTROL,
                    reinterpret_cast<uint8_t*>(&request), sizeof(request));

    if (response_body.size() != sizeof(ec_response_tpm_control))
    {
        stdplus::print(
            stderr, "Unexpected host command response size. Want {}; Got {}\n",
            sizeof(ec_response_tpm_control), response_body.size());
        throw ResponseFailure();
    }
    ec_response_tpm_control response_struct =
        stdplus::raw::copyFrom<ec_response_tpm_control>(response_body);

    if (response_struct.payload_size != sizeof(uint8_t))
    {
        uint16_t payload_size = response_struct.payload_size;
        stdplus::print(stderr,
                       "Unexpected response payload size. Want {}; Got {}\n",
                       sizeof(uint8_t), payload_size);
        throw ResponseFailure();
    }

    return response_struct.locality;
}

std::string payloadVersionString(const payload_region_state& state)
{
    std::string ret = std::to_string(state.version_major);
    ret.append(".");
    ret.append(std::to_string(state.version_minor));
    ret.append(".");
    ret.append(std::to_string(state.version_point));
    ret.append(".");
    ret.append(std::to_string(state.version_subpoint));
    return ret;
}

std::string firmwareMauvVersionString(const haven_image_version& ver)
{
    std::string ret = std::to_string(ver.epoch);
    ret.append(".");
    ret.append(std::to_string(ver.major));
    ret.append(".");
    ret.append(std::to_string(ver.minor));
    return ret;
}

haven_mauv EcUtilImpl::getHothFirmwareMauv() const
{
    const uint16_t mauvCommand =
        EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_MAUV;
    if (!isHostCommandSupported(mauvCommand))
    {
        throw CommandNotSupportedException(mauvCommand);
    }

    mauv_request request = {
        .category = HAVEN_MAUV,
        .state = MAUV_STATE_EFFECTIVE,
        .reserved_0 = 0,
    };

    std::vector<uint8_t> response_body = sendCommand(
        mauvCommand, reinterpret_cast<uint8_t*>(&request), sizeof(request));
    return stdplus::raw::copyFrom<haven_mauv>(response_body);
}

payload_status_response EcUtilImpl::getPayloadStatus() const
{
    std::vector<uint8_t> response_body =
        sendCommand(EC_CMD_BOARD_SPECIFIC_BASE + EC_PRV_CMD_HOTH_PAYLOAD_STATUS,
                    /*request_ptr=*/nullptr, /*request_size=*/0);

    if (response_body.empty())
    {
        stdplus::print(stderr, "PayloadStatus response is empty\n");
        throw ResponseFailure();
    }

    uint8_t version = response_body[0];
    if (version == PAYLOAD_STATUS_RESPONSE_VERSION)
    {
        if (response_body.size() != sizeof(payload_status_response))
        {
            stdplus::print(
                stderr,
                "PayloadStatus response size mismatch for version {}: want {}, got {}\n",
                version, sizeof(payload_status_response), response_body.size());
            throw ResponseFailure();
        }
    }
    else if (version > PAYLOAD_STATUS_RESPONSE_VERSION)
    {
        if (response_body.size() > sizeof(payload_status_response))
        {
            response_body.resize(sizeof(payload_status_response));
        }
        else if (response_body.size() < sizeof(payload_status_response))
        {
            stdplus::print(
                stderr,
                "PayloadStatus response size too small for version {}: want >= {}, got {}\n",
                version, sizeof(payload_status_response), response_body.size());
            throw ResponseFailure();
        }
    }
    else
    {
        stdplus::print(stderr,
                       "Unsupported PayloadStatus response version: {}\n",
                       version);
        throw ResponseFailure();
    }

    return stdplus::raw::copyFrom<payload_status_response>(response_body);
}

} // namespace internal

} // namespace hoth

} // namespace google
