// 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.

#pragma once

#include <boost/endian/arithmetic.hpp>

#include <cstdint>
#include <iterator>
#include <numeric>
#include <vector>

namespace google
{
namespace hoth
{
namespace internal
{

uint8_t constexpr SUPPORTED_STRUCT_VERSION = 3;

using boost::endian::big_uint16_t;
using boost::endian::big_uint32_t;
using boost::endian::little_uint16_t;
using boost::endian::little_uint32_t;
using boost::endian::little_uint8_t;

struct ReqHeader
{
    little_uint8_t struct_version;
    little_uint8_t checksum;
    little_uint16_t command;
    little_uint8_t command_version;
    little_uint8_t reserved;
    little_uint16_t data_len;
};

struct TpmHeader
{
    big_uint16_t tag;
    big_uint32_t size;
    big_uint32_t command_code;
};

struct RspHeader
{
    little_uint8_t struct_version;
    little_uint8_t checksum;
    little_uint16_t result;
    little_uint16_t data_len;
    little_uint16_t reserved;
};

struct CryptaHeader
{
    little_uint8_t major;
    little_uint8_t minor;
    little_uint16_t count;
};

struct CryptaParam
{
    little_uint16_t size;
    little_uint16_t reserved;
};

struct LoadTokenCmd
{
    ReqHeader reqHdr;
    CryptaHeader cryptaHdr;
};

struct CBKSlotCmd
{
    ReqHeader reqHdr;
    CryptaHeader cryptaHdr;
    CryptaParam cryptaParam;
    little_uint32_t slotId;
};

/* TODO Remove this default, and require users to get the mailbox
 * size from the SFDP GOOG table instead.
 */
constexpr uint32_t mailbox_size = 1024;

/* Calculates the checksum for a message with the given |contents|.
 *
 * The checksum for a series of bytes is an 8-bit unsigned sum of all of the
 * bytes.
 * To validate a checksum, simply pass all of the containers holding the
 * message contents to this function and check that it returns 0.
 *
 *
 * NOTE: this should not be used directly for the checksum field of a message.
 * You typically need to invert / remove this value from the checksum field of
 * of a message for the above property to become true.
 */
template <typename... Ts>
uint8_t calculateChecksum(Ts&&... ts)
{
    return (std::accumulate(std::begin(ts), std::end(ts), 0) + ...);
}

/* Populates |request_header| based on the other parameters provided.
 */
void populateReqHeader(uint16_t command, uint8_t command_version,
                       const void* request, size_t request_size,
                       ReqHeader* request_header);
size_t reqLen(const std::vector<uint8_t>& req);
size_t rspLen(const std::vector<uint8_t>& rsp);

std::vector<uint8_t> generateErrorResponse(uint8_t error);

} // namespace internal

} // namespace hoth

} // namespace google
