/*
 * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION &
 * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
 *
 * 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 "base.h"
#include "debug-token.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>

TEST(provideToken, testGoodEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_provide_token_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint8_t token[NSM_DEBUG_TOKEN_DATA_MAX_SIZE];
	for (uint32_t i = 0; i < NSM_DEBUG_TOKEN_DATA_MAX_SIZE; ++i) {
		token[i] = i;
	}

	auto rc = encode_nsm_provide_token_req(
	    0, token, NSM_DEBUG_TOKEN_DATA_MAX_SIZE, request);

	nsm_provide_token_req *req = (nsm_provide_token_req *)request->payload;

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	EXPECT_EQ(1, request->hdr.request);
	EXPECT_EQ(0, request->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type);

	EXPECT_EQ(NSM_PROVIDE_TOKEN, req->hdr.command);
	EXPECT_EQ(NSM_DEBUG_TOKEN_DATA_MAX_SIZE, req->hdr.data_size);
	EXPECT_EQ(
	    0, memcmp(token, req->token_data, NSM_DEBUG_TOKEN_DATA_MAX_SIZE));
}

TEST(provideToken, testBadEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_provide_token_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint8_t token[NSM_DEBUG_TOKEN_DATA_MAX_SIZE];
	for (uint32_t i = 0; i < NSM_DEBUG_TOKEN_DATA_MAX_SIZE; ++i) {
		token[i] = i;
	}

	auto rc = encode_nsm_provide_token_req(0, token, 0, request);

	EXPECT_EQ(NSM_ERR_INVALID_DATA, rc);
}

TEST(provideToken, testGoodDecodeResponse)
{
	std::vector<uint8_t> responseMsg{
	    0x10,
	    0xDE,		 // PCI VID: NVIDIA 0x10DE
	    0x00,		 // RQ=0, D=0, RSVD=0, INSTANCE_ID=0
	    0x8A,		 // OCP_TYPE=8, OCP_VER=10
	    NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE
	    NSM_PROVIDE_TOKEN,	 // command
	    NSM_SUCCESS,	 // completion code
	    0,
	    0, // reserved
	    0,
	    0, // data size
	};

	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();

	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	auto rc =
	    decode_nsm_provide_token_resp(response, msg_len, &cc, &reason_code);

	EXPECT_EQ(NSM_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
	EXPECT_EQ(0, reason_code);
}

// Test to cover line 208 in debug-token.c (message length validation)
TEST(provideToken, DISABLED_testDecodeResponseShortMessage)
{
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 NSM_RESPONSE_ERROR_LEN); // Too short
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());

	uint8_t cc = 0;
	uint16_t reason_code = 0;
	auto rc = decode_nsm_provide_token_resp(response, responseMsg.size(),
						&cc, &reason_code);

	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

// Test to cover line 203 in debug-token.c (error completion code path)
TEST(provideToken, decodeResponseErrorCompletionCode)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_non_success_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	// Set up error response with reason code
	auto resp =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	resp->command = NSM_PROVIDE_TOKEN;
	resp->completion_code = NSM_ERR_INVALID_DATA;
	resp->reason_code = htole16(0xCCCC);

	uint8_t cc = 0;
	uint16_t reason_code = 0;

	auto rc = decode_nsm_provide_token_resp(msg, msgBuf.size(), &cc,
						&reason_code);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERR_INVALID_DATA, cc);
	EXPECT_EQ(0xCCCC, reason_code);
}

TEST(disableTokens, testGoodEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_disable_tokens_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());

	auto rc = encode_nsm_disable_tokens_req(0, request);

	nsm_disable_tokens_req *req =
	    (nsm_disable_tokens_req *)request->payload;

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	EXPECT_EQ(1, request->hdr.request);
	EXPECT_EQ(0, request->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type);

	EXPECT_EQ(NSM_DISABLE_TOKENS, req->command);
	EXPECT_EQ(0, req->data_size);
}

TEST(disableTokens, testBadEncodeRequest)
{
	auto rc = encode_nsm_disable_tokens_req(0, nullptr);

	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

TEST(disableTokens, testGoodDecodeResponse)
{
	std::vector<uint8_t> responseMsg{
	    0x10,
	    0xDE,		 // PCI VID: NVIDIA 0x10DE
	    0x00,		 // RQ=0, D=0, RSVD=0, INSTANCE_ID=0
	    0x89,		 // OCP_TYPE=8, OCP_VER=9
	    NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE
	    NSM_DISABLE_TOKENS,	 // command
	    NSM_SUCCESS,	 // completion code
	    0,
	    0, // reserved
	    0,
	    0, // data size
	};

	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();

	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	auto rc = decode_nsm_disable_tokens_resp(response, msg_len, &cc,
						 &reason_code);

	EXPECT_EQ(NSM_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
	EXPECT_EQ(0, reason_code);
}

// Test to cover line 296 in debug-token.c (message length validation)
TEST(disableTokens, DISABLED_testDecodeResponseShortMessage)
{
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 NSM_RESPONSE_ERROR_LEN); // Too short
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());

	uint8_t cc = 0;
	uint16_t reason_code = 0;
	auto rc = decode_nsm_disable_tokens_resp(response, responseMsg.size(),
						 &cc, &reason_code);

	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

// Test to cover line 291 in debug-token.c (error completion code path)
TEST(disableTokens, decodeResponseErrorCompletionCode)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_non_success_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	// Set up error response with reason code
	auto resp =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	resp->command = NSM_DISABLE_TOKENS;
	resp->completion_code = NSM_ERR_INVALID_DATA;
	resp->reason_code = htole16(0xDDDD);

	uint8_t cc = 0;
	uint16_t reason_code = 0;

	auto rc = decode_nsm_disable_tokens_resp(msg, msgBuf.size(), &cc,
						 &reason_code);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERR_INVALID_DATA, cc);
	EXPECT_EQ(0xDDDD, reason_code);
}

TEST(queryTokenStatus, testGoodEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_query_token_status_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_FRC;

	auto rc = encode_nsm_query_token_status_req(0, token_type, request);

	nsm_query_token_status_req *req =
	    (nsm_query_token_status_req *)request->payload;

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	EXPECT_EQ(1, request->hdr.request);
	EXPECT_EQ(0, request->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type);

	EXPECT_EQ(NSM_QUERY_TOKEN_STATUS, req->hdr.command);
	EXPECT_EQ(1, req->hdr.data_size);
	EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_FRC, req->token_type);
}

TEST(queryTokenStatus, testBadEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_query_token_status_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint8_t token_type = 0xFF;

	auto rc = encode_nsm_query_token_status_req(
	    0, static_cast<nsm_debug_token_type>(token_type), request);

	EXPECT_EQ(NSM_ERR_INVALID_DATA, rc);
}

TEST(queryTokenStatus, testGoodDecodeResponse)
{
	uint16_t data_size =
	    sizeof(nsm_query_token_status_resp) - sizeof(nsm_common_resp);
	std::vector<uint8_t> responseMsg{
	    0x10,
	    0xDE,		    // PCI VID: NVIDIA 0x10DE
	    0x00,		    // RQ=0, D=0, RSVD=0, INSTANCE_ID=0
	    0x89,		    // OCP_TYPE=8, OCP_VER=9
	    NSM_TYPE_DIAGNOSTIC,    // NVIDIA_MSG_TYPE
	    NSM_QUERY_TOKEN_STATUS, // command
	    NSM_SUCCESS,	    // completion code
	    0,
	    0,						 // reserved
	    (uint8_t)(data_size & 0x00FF),		 // data size
	    (uint8_t)((data_size & 0xFF00) >> 8),	 // data size
	    NSM_DEBUG_TOKEN_TYPE_CRCS,			 // token type
	    0,						 // reserved
	    NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, // additional info
	    NSM_DEBUG_TOKEN_STATUS_NO_TOKEN_APPLIED,	 // status
	    0x12,					 // time left
	    0x34,					 // time left
	    0x56,					 // time left
	    0x78					 // time left
	};
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();
	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	nsm_debug_token_status status;
	nsm_debug_token_status_additional_info additional_info;
	nsm_debug_token_type token_type;
	uint32_t time_left;

	auto rc = decode_nsm_query_token_status_resp(
	    response, msg_len, &cc, &reason_code, &status, &additional_info,
	    &token_type, &time_left);

	EXPECT_EQ(NSM_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
	EXPECT_EQ(0, reason_code);
	EXPECT_EQ(NSM_DEBUG_TOKEN_STATUS_NO_TOKEN_APPLIED, status);
	EXPECT_EQ(NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE, additional_info);
	EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_CRCS, token_type);
	EXPECT_EQ(0x78563412, time_left);
}

// Test to cover line 400 in debug-token.c (error completion code path)
TEST(queryTokenStatus, decodeResponseErrorCompletionCode)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_non_success_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	// Set up error response with reason code
	auto resp =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	resp->command = NSM_QUERY_TOKEN_STATUS;
	resp->completion_code = NSM_ERR_INVALID_DATA;
	resp->reason_code = htole16(0xBBBB);

	uint8_t cc = 0;
	uint16_t reason_code = 0;
	nsm_debug_token_status status;
	nsm_debug_token_status_additional_info additional_info;
	nsm_debug_token_type token_type;
	uint32_t time_left;

	auto rc = decode_nsm_query_token_status_resp(
	    msg, msgBuf.size(), &cc, &reason_code, &status, &additional_info,
	    &token_type, &time_left);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERR_INVALID_DATA, cc);
	EXPECT_EQ(0xBBBB, reason_code);
}

TEST(queryTokenParameters, testGoodEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_query_token_parameters_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	nsm_debug_token_opcode token_opcode = NSM_DEBUG_TOKEN_OPCODE_CRCS;

	auto rc =
	    encode_nsm_query_token_parameters_req(0, token_opcode, request);

	nsm_query_token_parameters_req *req =
	    (nsm_query_token_parameters_req *)request->payload;

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	EXPECT_EQ(1, request->hdr.request);
	EXPECT_EQ(0, request->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type);

	EXPECT_EQ(NSM_QUERY_TOKEN_PARAMETERS, req->hdr.command);
	EXPECT_EQ(1, req->hdr.data_size);
	EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_CRCS, req->token_opcode);
}

TEST(queryTokenParameters, testBadEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_query_token_parameters_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint8_t token_opcode = 0xFF;

	auto rc = encode_nsm_query_token_parameters_req(
	    0, static_cast<nsm_debug_token_opcode>(token_opcode), request);

	EXPECT_EQ(NSM_ERR_INVALID_DATA, rc);
}

TEST(queryTokenParameters, testGoodDecodeResponse)
{
	std::vector<uint8_t> responseMsg{
	    0x10, 0xde, 0x00, 0x89, 0x04, 0x54, 0x00, 0x00, 0x00, 0x8c, 0x00,
	    0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	    0x00, 0x00, 0x1c, 0x76, 0xc0, 0xc4, 0xfc, 0xaf, 0x17, 0x24, 0x03,
	    0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x59, 0xbf, 0x4a, 0x04,
	    0x3d, 0xdd, 0x11, 0xef, 0xb9, 0x4f, 0xac, 0x1f, 0x6b, 0x01, 0xe5,
	    0xae, 0x1c, 0x76, 0xc0, 0xc4, 0xfc, 0xaf, 0x17, 0x24, 0x4e, 0x56,
	    0x44, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x30,
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x07, 0xde, 0x04, 0x48,
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xfe,
	    0x66, 0xd4, 0xb4, 0x5c, 0x4e, 0xae, 0xdc, 0x42, 0xdc, 0x25, 0xc7,
	    0xc6, 0x8c, 0xcf, 0x7c, 0x1d, 0x85, 0x7d, 0x6f, 0x63, 0x66, 0x7b,
	    0xaa, 0xdf, 0xb3, 0xcb, 0x4b, 0x37, 0x8d, 0x38};

	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();
	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	nsm_debug_token_request token_request;
	memset(&token_request, 0, sizeof(nsm_debug_token_request));

	auto rc = decode_nsm_query_token_parameters_resp(
	    response, msg_len, &cc, &reason_code, &token_request);

	EXPECT_EQ(NSM_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
	EXPECT_EQ(0, reason_code);
	EXPECT_EQ(sizeof(nsm_debug_token_request),
		  token_request.token_request_size);
	EXPECT_EQ(0, token_request.token_request_version);
	EXPECT_EQ(0x1C, token_request.device_uuid[0]);
	EXPECT_EQ(0x76, token_request.device_uuid[1]);
	EXPECT_EQ(0xC0, token_request.device_uuid[2]);
	EXPECT_EQ(0xC4, token_request.device_uuid[3]);
	EXPECT_EQ(0xFC, token_request.device_uuid[4]);
	EXPECT_EQ(0xAF, token_request.device_uuid[5]);
	EXPECT_EQ(0x17, token_request.device_uuid[6]);
	EXPECT_EQ(0x24, token_request.device_uuid[7]);
	EXPECT_EQ(NSM_DEBUG_TOKEN_DEVICE_TYPE_ID_NVSWITCH,
		  token_request.device_type);
	EXPECT_EQ(0, token_request.device_index);
	EXPECT_EQ(NSM_DEBUG_TOKEN_CHALLENGE_QUERY_STATUS_OK,
		  token_request.status);
	EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_CRDT, token_request.token_opcode);
	EXPECT_EQ(0x23, token_request.fw_version[0]);
	EXPECT_EQ(0x07, token_request.fw_version[1]);
	EXPECT_EQ(0xDE, token_request.fw_version[2]);
	EXPECT_EQ(0x04, token_request.fw_version[3]);
	EXPECT_EQ(0x48, token_request.fw_version[4]);
	EXPECT_EQ(0, token_request.session_id);
	EXPECT_EQ(0, token_request.challenge_version);
}

// Test to cover line 89 in debug-token.c (error completion code path)
TEST(queryTokenParameters, decodeResponseErrorCompletionCode)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_non_success_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	// Set up error response with reason code
	auto resp =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	resp->command = NSM_QUERY_TOKEN_PARAMETERS;
	resp->completion_code = NSM_ERR_INVALID_DATA;
	resp->reason_code = htole16(0xEEEE);

	uint8_t cc = 0;
	uint16_t reason_code = 0;
	nsm_debug_token_request token_request;
	memset(&token_request, 0, sizeof(nsm_debug_token_request));

	auto rc = decode_nsm_query_token_parameters_resp(
	    msg, msgBuf.size(), &cc, &reason_code, &token_request);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERR_INVALID_DATA, cc);
	EXPECT_EQ(0xEEEE, reason_code);
}

// Test to cover line 101 in debug-token.c (token_request_size validation)
TEST(queryTokenParameters, decodeResponseInvalidTokenRequestSize)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_parameters_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	auto resp =
	    reinterpret_cast<nsm_query_token_parameters_resp *>(msg->payload);
	resp->hdr.command = NSM_QUERY_TOKEN_PARAMETERS;
	resp->hdr.completion_code = NSM_SUCCESS;
	resp->hdr.data_size = htole16(sizeof(nsm_query_token_parameters_resp) -
				      sizeof(nsm_common_resp));

	// Set invalid token_request_size (should be
	// sizeof(nsm_debug_token_request))
	resp->token_request.token_request_size = 0;

	uint8_t cc = 0;
	uint16_t reason_code = 0;
	nsm_debug_token_request token_request;
	memset(&token_request, 0, sizeof(nsm_debug_token_request));

	auto rc = decode_nsm_query_token_parameters_resp(
	    msg, msgBuf.size(), &cc, &reason_code, &token_request);

	EXPECT_EQ(NSM_SW_ERROR_DATA, rc);
}

TEST(queryDeviceIDs, testGoodEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_query_device_ids_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());

	auto rc = encode_nsm_query_device_ids_req(0, request);

	nsm_query_device_ids_req *req =
	    (nsm_query_device_ids_req *)request->payload;

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	EXPECT_EQ(1, request->hdr.request);
	EXPECT_EQ(0, request->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type);

	EXPECT_EQ(NSM_QUERY_DEVICE_IDS, req->command);
	EXPECT_EQ(0, req->data_size);
}

TEST(queryDeviceIDs, testGoodEncodeResponse)
{
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 sizeof(nsm_query_device_ids_resp) + 8);

	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	uint8_t cc = NSM_SUCCESS;
	uint16_t reason_code = ERR_NULL;
	uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

	auto rc = encode_nsm_query_device_ids_resp(0, cc, reason_code,
						   device_id, 8, response);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, response->hdr.request);
	EXPECT_EQ(0, response->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type);

	nsm_query_device_ids_resp *resp =
	    (nsm_query_device_ids_resp *)response->payload;
	EXPECT_EQ(NSM_QUERY_DEVICE_IDS, resp->hdr.command);
	EXPECT_EQ(cc, resp->hdr.completion_code);
	EXPECT_EQ(8, le16toh(resp->hdr.data_size));
	EXPECT_EQ(0, memcmp(device_id, resp->data, 8));
}

TEST(queryDeviceIDs, testBadEncodeResponse)
{
	uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

	// null message
	auto rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL,
						   device_id, 8, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// null device_id
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 sizeof(nsm_query_device_ids_resp) + 8);
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL, nullptr,
					      8, response);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// zero device_id_len
	rc = encode_nsm_query_device_ids_resp(0, NSM_SUCCESS, ERR_NULL,
					      device_id, 0, response);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

TEST(queryDeviceIDs, testEncodeResponseWithError)
{
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 sizeof(nsm_query_device_ids_resp) + 8);

	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	uint8_t cc = NSM_ERROR;
	uint16_t reason_code = NSM_ERR_INVALID_DATA;
	uint8_t device_id[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};

	auto rc = encode_nsm_query_device_ids_resp(0, cc, reason_code,
						   device_id, 8, response);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, response->hdr.request);
	EXPECT_EQ(0, response->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type);
}

TEST(queryDeviceIDs, testGoodDecodeResponse)
{
	std::vector<uint8_t> responseMsg{
	    0x10,
	    0xDE,		  // PCI VID: NVIDIA 0x10DE
	    0x00,		  // RQ=0, D=0, RSVD=0, INSTANCE_ID=0
	    0x89,		  // OCP_TYPE=8, OCP_VER=9
	    NSM_TYPE_DIAGNOSTIC,  // NVIDIA_MSG_TYPE
	    NSM_QUERY_DEVICE_IDS, // command
	    NSM_SUCCESS,	  // completion code
	    0,
	    0,	  // reserved
	    8,	  // data size (little endian)
	    0,	  // data size
	    0x01, // ID
	    0x02, // ID
	    0x03, // ID
	    0x04, // ID
	    0x05, // ID
	    0x06, // ID
	    0x07, // ID
	    0x08, // ID
	};
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();
	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	uint8_t device_id[8];
	size_t device_id_len = 0;

	auto rc = decode_nsm_query_device_ids_resp(
	    response, msg_len, &cc, &reason_code, device_id, &device_id_len);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
	EXPECT_EQ(0, reason_code);
	EXPECT_EQ(8, device_id_len);
	EXPECT_EQ(0x01, device_id[0]);
	EXPECT_EQ(0x02, device_id[1]);
	EXPECT_EQ(0x03, device_id[2]);
	EXPECT_EQ(0x04, device_id[3]);
	EXPECT_EQ(0x05, device_id[4]);
	EXPECT_EQ(0x06, device_id[5]);
	EXPECT_EQ(0x07, device_id[6]);
	EXPECT_EQ(0x08, device_id[7]);
}

TEST(queryDeviceIDs, testDecodeResponseWithNullDeviceId)
{
	std::vector<uint8_t> responseMsg{
	    0x10,
	    0xDE,		  // PCI VID: NVIDIA 0x10DE
	    0x00,		  // RQ=0, D=0, RSVD=0, INSTANCE_ID=0
	    0x89,		  // OCP_TYPE=8, OCP_VER=9
	    NSM_TYPE_DIAGNOSTIC,  // NVIDIA_MSG_TYPE
	    NSM_QUERY_DEVICE_IDS, // command
	    NSM_SUCCESS,	  // completion code
	    0,
	    0,	  // reserved
	    8,	  // data size (little endian)
	    0,	  // data size
	    0x01, // ID
	    0x02, // ID
	    0x03, // ID
	    0x04, // ID
	    0x05, // ID
	    0x06, // ID
	    0x07, // ID
	    0x08, // ID
	};
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();
	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	size_t device_id_len = 0;

	// Test with null device_id pointer (should still work)
	auto rc = decode_nsm_query_device_ids_resp(
	    response, msg_len, &cc, &reason_code, nullptr, &device_id_len);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
	EXPECT_EQ(0, reason_code);
	EXPECT_EQ(8, device_id_len);
}

TEST(queryDeviceIDs, testBadDecodeResponse)
{
	uint8_t cc;
	uint16_t reason_code;
	uint8_t device_id[8];
	size_t device_id_len;

	// null message
	auto rc = decode_nsm_query_device_ids_resp(
	    nullptr, 100, &cc, &reason_code, device_id, &device_id_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// null parameters
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 sizeof(nsm_query_device_ids_resp) + 8);
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());

	rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(),
					      nullptr, &reason_code, device_id,
					      &device_id_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), &cc,
					      nullptr, device_id,
					      &device_id_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_query_device_ids_resp(response, responseMsg.size(), &cc,
					      &reason_code, device_id, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// insufficient message length
	rc = decode_nsm_query_device_ids_resp(response, 10, &cc, &reason_code,
					      device_id, &device_id_len);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

TEST(queryDeviceIDs, testDecodeResponseWithError)
{
	std::vector<uint8_t> responseMsg{
	    0x10,
	    0xDE,		  // PCI VID: NVIDIA 0x10DE
	    0x00,		  // RQ=0, D=0, RSVD=0, INSTANCE_ID=0
	    0x89,		  // OCP_TYPE=8, OCP_VER=9
	    NSM_TYPE_DIAGNOSTIC,  // NVIDIA_MSG_TYPE
	    NSM_QUERY_DEVICE_IDS, // command
	    NSM_ERROR,		  // completion code
	    ERR_TIMEOUT,	  // reason code
	    0,
	};
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();
	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	uint8_t device_id[8];
	size_t device_id_len = 0;

	auto rc = decode_nsm_query_device_ids_resp(
	    response, msg_len, &cc, &reason_code, device_id, &device_id_len);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERROR, cc);
	EXPECT_EQ(ERR_TIMEOUT, reason_code);
}

TEST(installToken, testGoodEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_install_token_req) + 100);

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint32_t chunk_offset = 0x12345678;
	uint32_t chunk_length = 64;
	uint32_t length_remaining = 1024;
	uint8_t data[64];
	for (uint32_t i = 0; i < chunk_length; ++i) {
		data[i] = i & 0xFF;
	}

	auto rc = encode_nsm_install_token_req(0, chunk_offset, chunk_length,
					       length_remaining, data, request);
	nsm_install_token_req *req = (nsm_install_token_req *)request->payload;

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(1, request->hdr.request);
	EXPECT_EQ(0, request->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type);
	EXPECT_EQ(NSM_INSTALL_TOKEN, req->hdr.command);
	EXPECT_EQ(sizeof(chunk_offset) + sizeof(chunk_length) +
		      sizeof(length_remaining) + chunk_length,
		  le16toh(req->hdr.data_size));
	EXPECT_EQ(chunk_offset, le32toh(req->chunk_offset));
	EXPECT_EQ(chunk_length, le32toh(req->chunk_length));
	EXPECT_EQ(length_remaining, le32toh(req->length_remaining));
	EXPECT_EQ(0, memcmp(data, req->data, chunk_length));
}

TEST(installToken, testBadEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_install_token_req) + 100);

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint8_t data[64];

	// null message
	auto rc = encode_nsm_install_token_req(0, 0, 64, 1024, data, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// null data
	rc = encode_nsm_install_token_req(0, 0, 64, 1024, nullptr, request);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

TEST(installToken, testGoodDecodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_install_token_req) + 100);

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint32_t expected_chunk_offset = 0x12345678;
	uint32_t expected_chunk_length = 64;
	uint32_t expected_length_remaining = 1024;
	uint8_t expected_data[64];
	for (uint32_t i = 0; i < expected_chunk_length; ++i) {
		expected_data[i] = i & 0xFF;
	}
	auto rc = encode_nsm_install_token_req(
	    0, expected_chunk_offset, expected_chunk_length,
	    expected_length_remaining, expected_data, request);
	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	uint32_t chunk_offset;
	uint32_t chunk_length;
	uint32_t length_remaining;
	uint8_t data[64];
	rc = decode_nsm_install_token_req(request, requestMsg.size(),
					  &chunk_offset, &chunk_length,
					  &length_remaining, data);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(expected_chunk_offset, chunk_offset);
	EXPECT_EQ(expected_chunk_length, chunk_length);
	EXPECT_EQ(expected_length_remaining, length_remaining);
	EXPECT_EQ(0, memcmp(expected_data, data, expected_chunk_length));
}

TEST(installToken, testBadDecodeRequest)
{
	uint32_t chunk_offset;
	uint32_t chunk_length;
	uint32_t length_remaining;
	uint8_t data[64];

	// null message
	auto rc = decode_nsm_install_token_req(nullptr, 100, &chunk_offset,
					       &chunk_length, &length_remaining,
					       data);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// null parameters
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_install_token_req));
	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());

	rc = decode_nsm_install_token_req(request, requestMsg.size(), nullptr,
					  &chunk_length, &length_remaining,
					  data);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_install_token_req(request, requestMsg.size(),
					  &chunk_offset, nullptr,
					  &length_remaining, data);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_install_token_req(request, requestMsg.size(),
					  &chunk_offset, &chunk_length, nullptr,
					  data);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// insufficient message length
	rc = decode_nsm_install_token_req(
	    request, 10, &chunk_offset, &chunk_length, &length_remaining, data);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

TEST(eraseToken, testGoodEncodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_erase_token_req));
	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint32_t token_type = 0x12345678;
	auto rc = encode_nsm_erase_token_req(0, token_type, request);
	nsm_erase_token_req *req = (nsm_erase_token_req *)request->payload;

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(1, request->hdr.request);
	EXPECT_EQ(0, request->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, request->hdr.nvidia_msg_type);
	EXPECT_EQ(NSM_ERASE_TOKEN, req->hdr.command);
	EXPECT_EQ(sizeof(token_type), req->hdr.data_size);
	EXPECT_EQ(token_type, le32toh(req->token_type));
}

TEST(eraseToken, testBadEncodeRequest)
{
	auto rc = encode_nsm_erase_token_req(0, 0x12345678, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

TEST(eraseToken, testGoodDecodeRequest)
{
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_erase_token_req));

	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());
	uint32_t expected_token_type = 0x87654321;
	auto rc = encode_nsm_erase_token_req(0, expected_token_type, request);
	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	uint32_t token_type;
	rc =
	    decode_nsm_erase_token_req(request, requestMsg.size(), &token_type);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(expected_token_type, token_type);
}

TEST(eraseToken, testBadDecodeRequest)
{
	uint32_t token_type;

	// null message
	auto rc = decode_nsm_erase_token_req(nullptr, 100, &token_type);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// null parameter
	std::vector<uint8_t> requestMsg(sizeof(nsm_msg_hdr) +
					sizeof(nsm_erase_token_req));
	auto request = reinterpret_cast<nsm_msg *>(requestMsg.data());

	rc = decode_nsm_erase_token_req(request, requestMsg.size(), nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// insufficient message length
	rc = decode_nsm_erase_token_req(request, 10, &token_type);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);

	// invalid data size
	nsm_erase_token_req *req = (nsm_erase_token_req *)request->payload;
	req->hdr.data_size = 10; // Invalid size
	rc =
	    decode_nsm_erase_token_req(request, requestMsg.size(), &token_type);
	EXPECT_EQ(NSM_SW_ERROR_DATA, rc);
}

TEST(queryToken, testGoodEncodeResponse)
{
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 sizeof(nsm_query_token_resp) + 100);

	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	uint8_t cc = NSM_SUCCESS;
	uint16_t reason_code = ERR_NULL;
	uint8_t tlv_payload[64];
	size_t tlv_payload_len = 32;
	for (size_t i = 0; i < tlv_payload_len; ++i) {
		tlv_payload[i] = i & 0xFF;
	}

	auto rc = encode_nsm_query_token_resp(0, cc, reason_code, tlv_payload,
					      tlv_payload_len, response);
	nsm_query_token_resp *resp = (nsm_query_token_resp *)response->payload;
	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, response->hdr.request);
	EXPECT_EQ(0, response->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, response->hdr.nvidia_msg_type);
	EXPECT_EQ(NSM_QUERY_TOKEN, resp->hdr.command);
	EXPECT_EQ(cc, resp->hdr.completion_code);
	EXPECT_EQ(tlv_payload_len, le16toh(resp->hdr.data_size));
	EXPECT_EQ(0, memcmp(tlv_payload, resp->tlv_payload, tlv_payload_len));
}

TEST(queryToken, testBadEncodeResponse)
{
	uint8_t tlv_payload[64] = {0};

	auto rc = encode_nsm_query_token_resp(0, NSM_SUCCESS, ERR_NULL,
					      tlv_payload, 32, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 862 in debug-token.c (error completion code path)
TEST(queryToken, errorCompletionCodeEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256);
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Test with non-success completion code to trigger error path
	uint8_t cc = NSM_ERR_INVALID_DATA;
	uint16_t reason_code = 0x8899;
	uint8_t tlv_payload[64] = {0};

	auto rc = encode_nsm_query_token_resp(0, cc, reason_code, tlv_payload,
					      32, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	// Verify error response structure
	auto resp_payload =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	EXPECT_EQ(NSM_QUERY_TOKEN, resp_payload->command);
	EXPECT_EQ(cc, resp_payload->completion_code);
	EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code));
}

TEST(queryToken, testGoodDecodeResponse)
{
	uint16_t data_size = 32;
	std::vector<uint8_t> responseMsg{
	    0x10,
	    0xDE,		 // PCI VID: NVIDIA 0x10DE
	    0x00,		 // RQ=0, D=0, RSVD=0, INSTANCE_ID=0
	    0x89,		 // OCP_TYPE=8, OCP_VER=9
	    NSM_TYPE_DIAGNOSTIC, // NVIDIA_MSG_TYPE
	    NSM_QUERY_TOKEN,	 // command
	    NSM_SUCCESS,	 // completion code
	    0,
	    0,					 // reserved
	    (uint8_t)(data_size & 0x00FF),	 // data size
	    (uint8_t)((data_size & 0xFF00) >> 8) // data size
	};
	for (uint16_t i = 0; i < data_size; ++i) {
		responseMsg.push_back(i & 0xFF);
	}

	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());
	size_t msg_len = responseMsg.size();
	uint8_t cc = 0;
	uint16_t reason_code = ERR_NULL;
	uint8_t tlv_payload[64];
	size_t tlv_payload_len = sizeof(tlv_payload);
	auto rc =
	    decode_nsm_query_token_resp(response, msg_len, &cc, &reason_code,
					tlv_payload, &tlv_payload_len);
	EXPECT_EQ(NSM_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
	EXPECT_EQ(0, reason_code);
	EXPECT_EQ(data_size, tlv_payload_len);
	for (uint16_t i = 0; i < data_size; ++i) {
		EXPECT_EQ(i & 0xFF, tlv_payload[i]);
	}
}

TEST(queryToken, testBadDecodeResponse)
{
	uint8_t cc;
	uint16_t reason_code;
	uint8_t tlv_payload[64];
	size_t tlv_payload_len;

	// null message
	auto rc = decode_nsm_query_token_resp(nullptr, 100, &cc, &reason_code,
					      tlv_payload, &tlv_payload_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// null parameters
	std::vector<uint8_t> responseMsg(sizeof(nsm_msg_hdr) +
					 sizeof(nsm_query_token_resp));
	auto response = reinterpret_cast<nsm_msg *>(responseMsg.data());

	rc = decode_nsm_query_token_resp(response, responseMsg.size(), nullptr,
					 &reason_code, tlv_payload,
					 &tlv_payload_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc =
	    decode_nsm_query_token_resp(response, responseMsg.size(), &cc,
					nullptr, tlv_payload, &tlv_payload_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_query_token_resp(response, responseMsg.size(), &cc,
					 &reason_code, tlv_payload, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// insufficient message length
	rc = decode_nsm_query_token_resp(response, 10, &cc, &reason_code,
					 tlv_payload, &tlv_payload_len);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

// Test to cover line 821 in debug-token.c (error completion code path)
TEST(queryToken, decodeResponseErrorCompletionCode)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_non_success_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	// Set up error response with reason code
	auto resp =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	resp->command = NSM_QUERY_TOKEN;
	resp->completion_code = NSM_ERR_INVALID_DATA;
	resp->reason_code = htole16(0x9AAA);

	uint8_t cc = 0;
	uint16_t reason_code = 0;
	uint8_t tlv_payload[64];
	size_t tlv_payload_len = sizeof(tlv_payload);

	auto rc =
	    decode_nsm_query_token_resp(msg, msgBuf.size(), &cc, &reason_code,
					tlv_payload, &tlv_payload_len);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERR_INVALID_DATA, cc);
	EXPECT_EQ(0x9AAA, reason_code);
}

// Tests for uncovered functions - Functional 90% coverage target

TEST(queryTokenParameters, goodTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_parameters_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req =
	    reinterpret_cast<nsm_query_token_parameters_req *>(msg->payload);
	req->hdr.command = NSM_QUERY_TOKEN_PARAMETERS;
	req->hdr.data_size = sizeof(req->token_opcode);
	req->token_opcode = NSM_DEBUG_TOKEN_OPCODE_RMCS;

	enum nsm_debug_token_opcode token_opcode =
	    NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC;

	auto rc = decode_nsm_query_token_parameters_req(msg, msgBuf.size(),
							&token_opcode);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_DEBUG_TOKEN_OPCODE_RMCS, token_opcode);
}

TEST(queryTokenParameters, badTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_parameters_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	enum nsm_debug_token_opcode token_opcode =
	    NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC;

	// Null message
	auto rc = decode_nsm_query_token_parameters_req(nullptr, msgBuf.size(),
							&token_opcode);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Null output parameter
	rc = decode_nsm_query_token_parameters_req(msg, msgBuf.size(), nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Invalid message length
	rc = decode_nsm_query_token_parameters_req(msg, 1, &token_opcode);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

// Test to cover line 38 in debug-token.c (data_size validation)
TEST(queryTokenParameters, decodeRequestInvalidDataSize)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_parameters_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req =
	    reinterpret_cast<nsm_query_token_parameters_req *>(msg->payload);
	req->hdr.command = NSM_QUERY_TOKEN_PARAMETERS;
	req->hdr.data_size =
	    0; // Invalid - should be at least sizeof(token_opcode)
	req->token_opcode = NSM_DEBUG_TOKEN_OPCODE_CRCS;

	enum nsm_debug_token_opcode token_opcode =
	    NSM_DEBUG_TOKEN_OPCODE_LINKX_FRC;

	auto rc = decode_nsm_query_token_parameters_req(msg, msgBuf.size(),
							&token_opcode);

	EXPECT_EQ(NSM_SW_ERROR_DATA, rc);
}

TEST(queryTokenParameters, goodTestEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_parameters_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	struct nsm_debug_token_request token_request = {};
	token_request.token_request_size =
	    sizeof(struct nsm_debug_token_request);

	auto rc = encode_nsm_query_token_parameters_resp(0, NSM_SUCCESS, 0,
							 &token_request, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, msg->hdr.request);
	EXPECT_EQ(0, msg->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type);

	auto resp =
	    reinterpret_cast<nsm_query_token_parameters_resp *>(msg->payload);
	EXPECT_EQ(NSM_QUERY_TOKEN_PARAMETERS, resp->hdr.command);
	EXPECT_EQ(NSM_SUCCESS, resp->hdr.completion_code);
}

TEST(queryTokenParameters, badTestEncodeResponse)
{
	struct nsm_debug_token_request token_request = {};

	// Null message
	auto rc = encode_nsm_query_token_parameters_resp(
	    0, NSM_SUCCESS, 0, &token_request, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 127 in debug-token.c (error completion code path)
TEST(queryTokenParameters, errorCompletionCodeEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256);
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	struct nsm_debug_token_request token_request = {};
	token_request.token_request_size =
	    sizeof(struct nsm_debug_token_request);

	// Test with non-success completion code to trigger error path
	uint8_t cc = NSM_ERR_INVALID_DATA;
	uint16_t reason_code = 0xABCD;

	auto rc = encode_nsm_query_token_parameters_resp(0, cc, reason_code,
							 &token_request, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	// Verify error response structure
	auto resp_payload =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	EXPECT_EQ(NSM_QUERY_TOKEN_PARAMETERS, resp_payload->command);
	EXPECT_EQ(cc, resp_payload->completion_code);
	EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code));
}

TEST(provideToken, goodTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_provide_token_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req = reinterpret_cast<nsm_provide_token_req *>(msg->payload);
	req->hdr.command = NSM_PROVIDE_TOKEN;
	req->hdr.data_size = 32;
	memset(req->token_data, 0xAB, 32);

	uint8_t token_data[NSM_DEBUG_TOKEN_DATA_MAX_SIZE] = {0};
	uint8_t token_data_len = 0;

	auto rc = decode_nsm_provide_token_req(msg, msgBuf.size(), token_data,
					       &token_data_len);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(32, token_data_len);
	EXPECT_EQ(0xAB, token_data[0]);
}

TEST(provideToken, badTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_provide_token_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	uint8_t token_data[NSM_DEBUG_TOKEN_DATA_MAX_SIZE] = {0};
	uint8_t token_data_len = 0;

	// Null message
	auto rc = decode_nsm_provide_token_req(nullptr, msgBuf.size(),
					       token_data, &token_data_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Null output parameters
	rc = decode_nsm_provide_token_req(msg, msgBuf.size(), nullptr,
					  &token_data_len);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_provide_token_req(msg, msgBuf.size(), token_data,
					  nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Invalid message length
	rc = decode_nsm_provide_token_req(msg, 1, token_data, &token_data_len);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

// Test to cover line 156 in debug-token.c (data_size = 0 validation)
TEST(provideToken, decodeRequestZeroDataSize)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_provide_token_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req = reinterpret_cast<nsm_provide_token_req *>(msg->payload);
	req->hdr.command = NSM_PROVIDE_TOKEN;
	req->hdr.data_size = 0; // Invalid - should be > 0

	uint8_t token_data[NSM_DEBUG_TOKEN_DATA_MAX_SIZE] = {0};
	uint8_t token_data_len = 0;

	auto rc = decode_nsm_provide_token_req(msg, msgBuf.size(), token_data,
					       &token_data_len);

	EXPECT_EQ(NSM_SW_ERROR_DATA, rc);
}

TEST(provideToken, goodTestEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = encode_nsm_provide_token_resp(0, NSM_SUCCESS, 0, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, msg->hdr.request);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type);
}

TEST(provideToken, badTestEncodeResponse)
{
	// Null message
	auto rc = encode_nsm_provide_token_resp(0, NSM_SUCCESS, 0, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 232 in debug-token.c (error completion code path)
TEST(provideToken, errorCompletionCodeEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256);
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Test with non-success completion code to trigger error path
	uint8_t cc = NSM_ERR_INVALID_DATA;
	uint16_t reason_code = 0x9876;

	auto rc = encode_nsm_provide_token_resp(0, cc, reason_code, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	// Verify error response structure
	auto resp_payload =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	EXPECT_EQ(NSM_PROVIDE_TOKEN, resp_payload->command);
	EXPECT_EQ(cc, resp_payload->completion_code);
	EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code));
}

TEST(disableTokens, goodTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_disable_tokens_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = decode_nsm_disable_tokens_req(msg, msgBuf.size());

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

TEST(disableTokens, badTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_disable_tokens_req));

	// Null message
	auto rc = decode_nsm_disable_tokens_req(nullptr, msgBuf.size());
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Invalid message length
	rc = decode_nsm_disable_tokens_req(msg, 1);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

TEST(disableTokens, goodTestEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_disable_tokens_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = encode_nsm_disable_tokens_resp(0, NSM_SUCCESS, 0, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, msg->hdr.request);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type);
}

TEST(disableTokens, badTestEncodeResponse)
{
	// Null message
	auto rc = encode_nsm_disable_tokens_resp(0, NSM_SUCCESS, 0, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 320 in debug-token.c (error completion code path)
TEST(disableTokens, errorCompletionCodeEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256);
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Test with non-success completion code to trigger error path
	uint8_t cc = NSM_ERR_INVALID_DATA;
	uint16_t reason_code = 0x5432;

	auto rc = encode_nsm_disable_tokens_resp(0, cc, reason_code, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	// Verify error response structure
	auto resp_payload =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	EXPECT_EQ(NSM_DISABLE_TOKENS, resp_payload->command);
	EXPECT_EQ(cc, resp_payload->completion_code);
	EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code));
}

TEST(queryTokenStatus, goodTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_status_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req = reinterpret_cast<nsm_query_token_status_req *>(msg->payload);
	req->hdr.command = NSM_QUERY_TOKEN_STATUS;
	req->hdr.data_size = sizeof(req->token_type);
	req->token_type = NSM_DEBUG_TOKEN_TYPE_FRC;

	enum nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_CRCS;

	auto rc =
	    decode_nsm_query_token_status_req(msg, msgBuf.size(), &token_type);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_DEBUG_TOKEN_TYPE_FRC, token_type);
}

TEST(queryTokenStatus, badTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_status_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	enum nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_CRCS;

	// Null message
	auto rc = decode_nsm_query_token_status_req(nullptr, msgBuf.size(),
						    &token_type);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Null output parameter
	rc = decode_nsm_query_token_status_req(msg, msgBuf.size(), nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Invalid message length
	rc = decode_nsm_query_token_status_req(msg, 1, &token_type);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

// Test to cover line 347 in debug-token.c (data_size validation)
TEST(queryTokenStatus, decodeRequestInvalidDataSize)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_status_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req = reinterpret_cast<nsm_query_token_status_req *>(msg->payload);
	req->hdr.command = NSM_QUERY_TOKEN_STATUS;
	req->hdr.data_size =
	    0; // Invalid - should be at least sizeof(token_type)
	req->token_type = NSM_DEBUG_TOKEN_TYPE_CRCS;

	enum nsm_debug_token_type token_type = NSM_DEBUG_TOKEN_TYPE_FRC;

	auto rc =
	    decode_nsm_query_token_status_req(msg, msgBuf.size(), &token_type);

	EXPECT_EQ(NSM_SW_ERROR_DATA, rc);
}

TEST(queryTokenStatus, goodTestEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_status_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = encode_nsm_query_token_status_resp(
	    0, NSM_SUCCESS, 0, NSM_DEBUG_TOKEN_STATUS_DEBUG_SESSION_ACTIVE,
	    NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE,
	    NSM_DEBUG_TOKEN_TYPE_FRC, 3600, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, msg->hdr.request);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type);

	auto resp =
	    reinterpret_cast<nsm_query_token_status_resp *>(msg->payload);
	EXPECT_EQ(NSM_QUERY_TOKEN_STATUS, resp->hdr.command);
	EXPECT_EQ(NSM_SUCCESS, resp->hdr.completion_code);
}

TEST(queryTokenStatus, badTestEncodeResponse)
{
	// Null message
	auto rc = encode_nsm_query_token_status_resp(
	    0, NSM_SUCCESS, 0, NSM_DEBUG_TOKEN_STATUS_DEBUG_SESSION_ACTIVE,
	    NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE,
	    NSM_DEBUG_TOKEN_TYPE_FRC, 3600, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 440 in debug-token.c (error completion code path)
TEST(queryTokenStatus, errorCompletionCodeEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256);
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Test with non-success completion code to trigger error path
	uint8_t cc = NSM_ERR_INVALID_DATA;
	uint16_t reason_code = 0x1122;

	auto rc = encode_nsm_query_token_status_resp(
	    0, cc, reason_code, NSM_DEBUG_TOKEN_STATUS_DEBUG_SESSION_ACTIVE,
	    NSM_DEBUG_TOKEN_STATUS_ADDITIONAL_INFO_NONE,
	    NSM_DEBUG_TOKEN_TYPE_FRC, 3600, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	// Verify error response structure
	auto resp_payload =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	EXPECT_EQ(NSM_QUERY_TOKEN_STATUS, resp_payload->command);
	EXPECT_EQ(cc, resp_payload->completion_code);
	EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code));
}

TEST(queryDeviceIds, goodTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_device_ids_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = decode_nsm_query_device_ids_req(msg, msgBuf.size());

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

TEST(queryDeviceIds, badTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_device_ids_req));

	// Null message
	auto rc = decode_nsm_query_device_ids_req(nullptr, msgBuf.size());
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Invalid message length
	rc = decode_nsm_query_device_ids_req(msg, 1);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

TEST(installToken, goodTestDecodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_install_token_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	auto resp = reinterpret_cast<nsm_install_token_resp *>(msg->payload);
	resp->command = NSM_INSTALL_TOKEN;
	resp->completion_code = NSM_SUCCESS;

	uint8_t cc = 0;
	uint16_t reason_code = 0;

	auto rc = decode_nsm_install_token_resp(msg, msgBuf.size(), &cc,
						&reason_code);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
}

TEST(installToken, badTestDecodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_install_token_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	uint8_t cc = 0;
	uint16_t reason_code = 0;

	// Null message
	auto rc = decode_nsm_install_token_resp(nullptr, msgBuf.size(), &cc,
						&reason_code);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Null output parameters
	rc = decode_nsm_install_token_resp(msg, msgBuf.size(), nullptr,
					   &reason_code);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_install_token_resp(msg, msgBuf.size(), &cc, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 640 in debug-token.c (error completion code path)
TEST(installToken, decodeResponseErrorCompletionCode)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_non_success_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	// Set up error response with reason code
	auto resp =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	resp->command = NSM_INSTALL_TOKEN;
	resp->completion_code = NSM_ERR_INVALID_DATA; // Error completion code
	resp->reason_code = htole16(0x3344);

	uint8_t cc = 0;
	uint16_t reason_code = 0;

	// decode should succeed but return early due to cc != NSM_SUCCESS
	auto rc = decode_nsm_install_token_resp(msg, msgBuf.size(), &cc,
						&reason_code);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERR_INVALID_DATA, cc);
	EXPECT_EQ(0x3344, reason_code);
}

TEST(installToken, goodTestEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_install_token_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = encode_nsm_install_token_resp(0, NSM_SUCCESS, 0, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, msg->hdr.request);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type);
}

TEST(installToken, badTestEncodeResponse)
{
	// Null message
	auto rc = encode_nsm_install_token_resp(0, NSM_SUCCESS, 0, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 664 in debug-token.c (error completion code path)
TEST(installToken, errorCompletionCodeEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256);
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Test with non-success completion code to trigger error path
	uint8_t cc = NSM_ERR_INVALID_DATA;
	uint16_t reason_code = 0x6677;

	auto rc = encode_nsm_install_token_resp(0, cc, reason_code, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	// Verify error response structure
	auto resp_payload =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	EXPECT_EQ(NSM_INSTALL_TOKEN, resp_payload->command);
	EXPECT_EQ(cc, resp_payload->completion_code);
	EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code));
}

TEST(eraseToken, goodTestDecodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_erase_token_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	auto resp = reinterpret_cast<nsm_erase_token_resp *>(msg->payload);
	resp->command = NSM_ERASE_TOKEN;
	resp->completion_code = NSM_SUCCESS;

	uint8_t cc = 0;
	uint16_t reason_code = 0;

	auto rc =
	    decode_nsm_erase_token_resp(msg, msgBuf.size(), &cc, &reason_code);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_SUCCESS, cc);
}

TEST(eraseToken, badTestDecodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_erase_token_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	uint8_t cc = 0;
	uint16_t reason_code = 0;

	// Null message
	auto rc = decode_nsm_erase_token_resp(nullptr, msgBuf.size(), &cc,
					      &reason_code);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	// Null output parameters
	rc = decode_nsm_erase_token_resp(msg, msgBuf.size(), nullptr,
					 &reason_code);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	rc = decode_nsm_erase_token_resp(msg, msgBuf.size(), &cc, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 733 in debug-token.c (error completion code path)
TEST(eraseToken, decodeResponseErrorCompletionCode)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_non_success_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Set up valid response header
	msg->hdr.pci_vendor_id = htobe16(PCI_VENDOR_ID);
	msg->hdr.ocp_type = OCP_TYPE;
	msg->hdr.ocp_version = OCP_VERSION;

	// Set up error response with reason code
	auto resp =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	resp->command = NSM_ERASE_TOKEN;
	resp->completion_code = NSM_ERR_INVALID_DATA;
	resp->reason_code = htole16(0x5566);

	uint8_t cc = 0;
	uint16_t reason_code = 0;

	auto rc =
	    decode_nsm_erase_token_resp(msg, msgBuf.size(), &cc, &reason_code);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(NSM_ERR_INVALID_DATA, cc);
	EXPECT_EQ(0x5566, reason_code);
}

TEST(eraseToken, goodTestEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_erase_token_resp));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = encode_nsm_erase_token_resp(0, NSM_SUCCESS, 0, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(0, msg->hdr.request);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type);
}

TEST(eraseToken, badTestEncodeResponse)
{
	// Null message
	auto rc = encode_nsm_erase_token_resp(0, NSM_SUCCESS, 0, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Test to cover line 757 in debug-token.c (error completion code path)
TEST(eraseToken, errorCompletionCodeEncodeResponse)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) + 256);
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Test with non-success completion code to trigger error path
	uint8_t cc = NSM_ERR_INVALID_DATA;
	uint16_t reason_code = 0x7788;

	auto rc = encode_nsm_erase_token_resp(0, cc, reason_code, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);

	// Verify error response structure
	auto resp_payload =
	    reinterpret_cast<nsm_common_non_success_resp *>(msg->payload);
	EXPECT_EQ(NSM_ERASE_TOKEN, resp_payload->command);
	EXPECT_EQ(cc, resp_payload->completion_code);
	EXPECT_EQ(reason_code, le16toh(resp_payload->reason_code));
}

TEST(queryToken, goodTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req = reinterpret_cast<nsm_query_token_req *>(msg->payload);
	req->command = NSM_QUERY_TOKEN;
	req->data_size = 0;

	auto rc = decode_nsm_query_token_req(msg, msgBuf.size());

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

TEST(queryToken, badTestDecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_req));

	// Null message
	auto rc = decode_nsm_query_token_req(nullptr, msgBuf.size());
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);

	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	// Invalid message length
	rc = decode_nsm_query_token_req(msg, 1);
	EXPECT_EQ(NSM_SW_ERROR_LENGTH, rc);
}

// Test to cover line 781 in debug-token.c (non-zero data_size validation)
TEST(queryToken, decodeRequestInvalidDataSize)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto req = reinterpret_cast<nsm_query_token_req *>(msg->payload);
	req->command = NSM_QUERY_TOKEN;
	req->data_size = 1; // Invalid - should be 0

	auto rc = decode_nsm_query_token_req(msg, msgBuf.size());

	EXPECT_EQ(NSM_SW_ERROR_DATA, rc);
}

TEST(queryToken, goodTestEncodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_query_token_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());

	auto rc = encode_nsm_query_token_req(0, msg);

	EXPECT_EQ(NSM_SW_SUCCESS, rc);
	EXPECT_EQ(1, msg->hdr.request);
	EXPECT_EQ(0, msg->hdr.datagram);
	EXPECT_EQ(NSM_TYPE_DIAGNOSTIC, msg->hdr.nvidia_msg_type);

	auto req = reinterpret_cast<nsm_query_token_req *>(msg->payload);
	EXPECT_EQ(NSM_QUERY_TOKEN, req->command);
	EXPECT_EQ(0, req->data_size);
}

TEST(queryToken, badTestEncodeRequest)
{
	// Null message
	auto rc = encode_nsm_query_token_req(0, nullptr);
	EXPECT_EQ(NSM_SW_ERROR_NULL, rc);
}

// Simple decode tests
TEST(DisableTokens, DecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	auto rc = decode_nsm_disable_tokens_req(msg, msgBuf.size());
	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

TEST(QueryDeviceIds, DecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	auto rc = decode_nsm_query_device_ids_req(msg, msgBuf.size());
	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

TEST(QueryToken, DecodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	auto rc = decode_nsm_query_token_req(msg, msgBuf.size());
	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

// More simple encode tests
TEST(DisableTokens, EncodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	auto rc = encode_nsm_disable_tokens_req(0, msg);
	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

TEST(QueryDeviceIds, EncodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	auto rc = encode_nsm_query_device_ids_req(0, msg);
	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

TEST(QueryToken, EncodeRequest)
{
	std::vector<uint8_t> msgBuf(sizeof(nsm_msg_hdr) +
				    sizeof(nsm_common_req));
	auto msg = reinterpret_cast<nsm_msg *>(msgBuf.data());
	auto rc = encode_nsm_query_token_req(0, msg);
	EXPECT_EQ(NSM_SW_SUCCESS, rc);
}

// Branch coverage: encode_nsm_query_token_parameters_req L49
TEST(DebugTokenNullBranch, EncodeQueryTokenParamReq_NullMsg)
{
	auto rc = encode_nsm_query_token_parameters_req(
	    0, NSM_DEBUG_TOKEN_OPCODE_RMCS, nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// Branch coverage: encode_nsm_query_token_parameters_resp L112
TEST(DebugTokenNullBranch, EncodeQueryTokenParamResp_NullMsg)
{
	auto rc = encode_nsm_query_token_parameters_resp(0, NSM_SUCCESS, 0,
							 nullptr, nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// Branch coverage: decode_nsm_query_token_parameters_resp L83
// (msg == NULL || token_request == NULL)
TEST(DebugTokenNullBranch, DecodeQueryTokenParamResp_NullMsg)
{
	uint8_t cc = 0;
	uint16_t reason_code = 0;
	struct nsm_debug_token_request token_request = {};
	auto rc = decode_nsm_query_token_parameters_resp(
	    nullptr, 0, &cc, &reason_code, &token_request);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

TEST(DebugTokenNullBranch, DecodeQueryTokenParamResp_NullTokenRequest)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0);
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason_code = 0;
	auto rc = decode_nsm_query_token_parameters_resp(msg, buf.size(), &cc,
							 &reason_code, nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// Branch coverage: encode_nsm_provide_token_req L168
// (msg == NULL || token_data == NULL)
TEST(DebugTokenNullBranch, EncodeProvideTokenReq_NullMsg)
{
	uint8_t token_data[4] = {};
	auto rc = encode_nsm_provide_token_req(0, token_data, 4, nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

TEST(DebugTokenNullBranch, EncodeProvideTokenReq_NullTokenData)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0);
	auto *msg = reinterpret_cast<nsm_msg *>(buf.data());
	auto rc = encode_nsm_provide_token_req(0, nullptr, 4, msg);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// Branch coverage: encode_nsm_query_token_status_req L358
TEST(DebugTokenNullBranch, EncodeQueryTokenStatusReq_NullMsg)
{
	auto rc = encode_nsm_query_token_status_req(0, NSM_DEBUG_TOKEN_TYPE_FRC,
						    nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// Branch coverage: decode_nsm_query_token_status_resp L393
// (msg == NULL || status == NULL || additional_info == NULL || ...)
TEST(DebugTokenNullBranch, DecodeQueryTokenStatusResp_NullMsg)
{
	uint8_t cc = 0;
	uint16_t reason_code = 0;
	enum nsm_debug_token_status status = {};
	enum nsm_debug_token_status_additional_info additional_info = {};
	enum nsm_debug_token_type token_type = {};
	uint32_t time_left = 0;
	auto rc = decode_nsm_query_token_status_resp(
	    nullptr, 0, &cc, &reason_code, &status, &additional_info,
	    &token_type, &time_left);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

TEST(DebugTokenNullBranch, DecodeQueryTokenStatusResp_NullStatus)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0);
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason_code = 0;
	enum nsm_debug_token_status_additional_info additional_info = {};
	enum nsm_debug_token_type token_type = {};
	uint32_t time_left = 0;
	auto rc = decode_nsm_query_token_status_resp(
	    msg, buf.size(), &cc, &reason_code, nullptr, &additional_info,
	    &token_type, &time_left);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// Branch coverage: encode_nsm_query_device_ids_req L474
TEST(DebugTokenNullBranch, EncodeQueryDeviceIdsReq_NullMsg)
{
	auto rc = encode_nsm_query_device_ids_req(0, nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_DATA);
}

// ---------------------------------------------------------------------------
// Null checks for secondary conditions (cc/reason_code/time_left/etc == NULL)
// ---------------------------------------------------------------------------

// decode_nsm_provide_token_resp L197: cc == NULL
TEST(DebugTokenNullBranch, DecodeProvideTokenResp_NullCc)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 8, 0);
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint16_t reason_code = 0;
	auto rc = decode_nsm_provide_token_resp(msg, buf.size(), nullptr,
						&reason_code);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// decode_nsm_disable_tokens_resp L285: cc == NULL
TEST(DebugTokenNullBranch, DecodeDisableTokensResp_NullCc)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 8, 0);
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint16_t reason_code = 0;
	auto rc = decode_nsm_disable_tokens_resp(msg, buf.size(), nullptr,
						 &reason_code);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// decode_nsm_query_token_status_resp L394: token_type == NULL
TEST(DebugTokenNullBranch, DecodeQueryTokenStatusResp_NullTokenType)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 8, 0);
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason_code = 0;
	enum nsm_debug_token_status status = {};
	enum nsm_debug_token_status_additional_info additional_info = {};
	uint32_t time_left = 0;
	auto rc = decode_nsm_query_token_status_resp(
	    msg, buf.size(), &cc, &reason_code, &status, &additional_info,
	    nullptr, &time_left);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// ---------------------------------------------------------------------------
// Pack-fail branches (instance_id > NSM_INSTANCE_MAX = 31)
// ---------------------------------------------------------------------------

static std::vector<uint8_t> g_dbg_buf(1024, 0);
static nsm_msg *g_dbg_msg()
{
	return reinterpret_cast<nsm_msg *>(g_dbg_buf.data());
}

// encode_nsm_query_token_parameters_req L66
TEST(DebugTokenPackFailBranch, EncodeQueryTokenParamReq_PackFail)
{
	auto rc = encode_nsm_query_token_parameters_req(
	    32, NSM_DEBUG_TOKEN_OPCODE_RMCS, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_query_token_parameters_resp L122
TEST(DebugTokenPackFailBranch, EncodeQueryTokenParamResp_PackFail)
{
	auto rc = encode_nsm_query_token_parameters_resp(32, NSM_SUCCESS, 0,
							 nullptr, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_provide_token_req L181
TEST(DebugTokenPackFailBranch, EncodeProvideTokenReq_PackFail)
{
	uint8_t token_data[1] = {0};
	auto rc = encode_nsm_provide_token_req(32, token_data, 1, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_provide_token_resp L227
TEST(DebugTokenPackFailBranch, EncodeProvideTokenResp_PackFail)
{
	auto rc =
	    encode_nsm_provide_token_resp(32, NSM_SUCCESS, 0, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_disable_tokens_req L270
TEST(DebugTokenPackFailBranch, EncodeDisableTokensReq_PackFail)
{
	auto rc = encode_nsm_disable_tokens_req(32, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_disable_tokens_resp L315
TEST(DebugTokenPackFailBranch, EncodeDisableTokensResp_PackFail)
{
	auto rc =
	    encode_nsm_disable_tokens_resp(32, NSM_SUCCESS, 0, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_query_token_status_req L374
TEST(DebugTokenPackFailBranch, EncodeQueryTokenStatusReq_PackFail)
{
	auto rc = encode_nsm_query_token_status_req(
	    32, NSM_DEBUG_TOKEN_TYPE_FRC, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_query_token_status_resp L435
TEST(DebugTokenPackFailBranch, EncodeQueryTokenStatusResp_PackFail)
{
	auto rc = encode_nsm_query_token_status_resp(
	    32, NSM_SUCCESS, 0, static_cast<nsm_debug_token_status>(0),
	    static_cast<nsm_debug_token_status_additional_info>(0),
	    static_cast<nsm_debug_token_type>(0), 0, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_query_device_ids_req L484
TEST(DebugTokenPackFailBranch, EncodeQueryDeviceIdsReq_PackFail)
{
	auto rc = encode_nsm_query_device_ids_req(32, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_query_device_ids_resp L543
TEST(DebugTokenPackFailBranch, EncodeQueryDeviceIdsResp_PackFail)
{
	uint8_t dev_id[1] = {0};
	auto rc = encode_nsm_query_device_ids_resp(32, NSM_SUCCESS, 0, dev_id,
						   1, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_install_token_req L613
TEST(DebugTokenPackFailBranch, EncodeInstallTokenReq_PackFail)
{
	uint8_t data[1] = {0};
	auto rc = encode_nsm_install_token_req(32, 0, 0, 0, data, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_install_token_resp L659
TEST(DebugTokenPackFailBranch, EncodeInstallTokenResp_PackFail)
{
	auto rc =
	    encode_nsm_install_token_resp(32, NSM_SUCCESS, 0, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_erase_token_req L711
TEST(DebugTokenPackFailBranch, EncodeEraseTokenReq_PackFail)
{
	auto rc = encode_nsm_erase_token_req(32, 0, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_erase_token_resp L752
TEST(DebugTokenPackFailBranch, EncodeEraseTokenResp_PackFail)
{
	auto rc = encode_nsm_erase_token_resp(32, NSM_SUCCESS, 0, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_query_token_req L799
TEST(DebugTokenPackFailBranch, EncodeQueryTokenReq_PackFail)
{
	auto rc = encode_nsm_query_token_req(32, g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// encode_nsm_query_token_resp L857
TEST(DebugTokenPackFailBranch, EncodeQueryTokenResp_PackFail)
{
	uint8_t payload[1] = {0};
	auto rc = encode_nsm_query_token_resp(32, NSM_SUCCESS, 0, payload, 1,
					      g_dbg_msg());
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// ===========================================================================
// rc != NSM_SW_SUCCESS branches (B0 of || condition)
// Pass msg with error CC + wrong size → decode_reason_code_and_cc returns
// NSM_SW_ERROR_LENGTH, so rc != NSM_SW_SUCCESS → TRUE branch taken
// ===========================================================================
// Error-CC buffer helper: large buffer with completion_code = NSM_ERROR
// payload[1] (not payload[0]) is completion_code in nsm_common_resp
static std::vector<uint8_t> makeErrCcBuf(size_t size = sizeof(nsm_msg_hdr) +
						       100)
{
	std::vector<uint8_t> buf(size, 0);
	buf[sizeof(nsm_msg_hdr) + 1] = 0xFF; // completion_code != NSM_SUCCESS
	return buf;
}

// decode_nsm_query_token_parameters_resp L88 — rc != NSM_SW_SUCCESS
TEST(DebugTokenBranches, DecodeQueryTokenParamResp_RcFail)
{
	auto buf = makeErrCcBuf();
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason = 0;
	struct nsm_debug_token_request token_req = {};
	auto rc = decode_nsm_query_token_parameters_resp(msg, buf.size(), &cc,
							 &reason, &token_req);
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// decode_nsm_provide_token_resp L197 — rc != NSM_SW_SUCCESS
TEST(DebugTokenBranches, DecodeProvideTokenResp_RcFail)
{
	auto buf = makeErrCcBuf();
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason = 0;
	auto rc = decode_nsm_provide_token_resp(msg, buf.size(), &cc, &reason);
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// decode_nsm_disable_tokens_resp L285 — reason_code=NULL
TEST(DebugTokenBranches, DecodeDisableTokensResp_NullReasonCode)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0);
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	auto rc = decode_nsm_disable_tokens_resp(msg, buf.size(), &cc, nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// decode_nsm_disable_tokens_resp L290 — rc != NSM_SW_SUCCESS
TEST(DebugTokenBranches, DecodeDisableTokensResp_RcFail)
{
	auto buf = makeErrCcBuf();
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason = 0;
	auto rc = decode_nsm_disable_tokens_resp(msg, buf.size(), &cc, &reason);
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// decode_nsm_query_token_status_resp L394 — time_left=NULL
TEST(DebugTokenBranches, DecodeQueryTokenStatusResp_NullTimeLeft)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + 32, 0);
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason = 0;
	enum nsm_debug_token_status status = {};
	enum nsm_debug_token_status_additional_info additional_info = {};
	enum nsm_debug_token_type token_type = {};
	auto rc = decode_nsm_query_token_status_resp(
	    msg, buf.size(), &cc, &reason, &status, &additional_info,
	    &token_type, nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_NULL);
}

// decode_nsm_query_token_status_resp L399 — rc != NSM_SW_SUCCESS
TEST(DebugTokenBranches, DecodeQueryTokenStatusResp_RcFail)
{
	auto buf = makeErrCcBuf();
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason = 0;
	enum nsm_debug_token_status status = {};
	enum nsm_debug_token_status_additional_info additional_info = {};
	enum nsm_debug_token_type token_type = {};
	uint32_t time_left = 0;
	auto rc = decode_nsm_query_token_status_resp(
	    msg, buf.size(), &cc, &reason, &status, &additional_info,
	    &token_type, &time_left);
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// decode_nsm_query_token_resp L820 — rc != NSM_SW_SUCCESS
TEST(DebugTokenBranches, DecodeQueryTokenResp_RcFail)
{
	auto buf = makeErrCcBuf();
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint8_t cc = 0;
	uint16_t reason = 0;
	size_t tlv_payload_len = 0;
	auto rc = decode_nsm_query_token_resp(msg, buf.size(), &cc, &reason,
					      nullptr, &tlv_payload_len);
	EXPECT_NE(rc, NSM_SW_SUCCESS);
}

// ===========================================================================
// decode_nsm_install_token_req branch coverage
// L577: data_size too small, L588: size mismatch, L591: data=NULL
// ===========================================================================

// L577 TRUE: data_size < minimum (zero-fill → data_size=0)
TEST(DebugTokenBranches, DecodeInstallTokenReq_DataSizeTooSmall)
{
	std::vector<uint8_t> buf(
	    sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req), 0);
	// data_size = 0 (zero-fill) < 13 → L577 TRUE
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint32_t chunk_offset = 0, chunk_length = 0, length_remaining = 0;
	auto rc = decode_nsm_install_token_req(msg, buf.size(), &chunk_offset,
					       &chunk_length, &length_remaining,
					       nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH);
}

// L588 TRUE: data_size >= 13 but != expected (data_size=13, chunk_length=5)
TEST(DebugTokenBranches, DecodeInstallTokenReq_DataSizeMismatch)
{
	std::vector<uint8_t> buf(
	    sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req) + 10, 0);
	// data_size at payload offset 2 = 13 (LE16): passes L577
	buf[sizeof(nsm_msg_hdr) + 2] = 13;
	buf[sizeof(nsm_msg_hdr) + 3] = 0;
	// chunk_length at payload offset 10 = 5: expected_size = 12+5=17 ≠ 13
	buf[sizeof(nsm_msg_hdr) + 10] = 5;
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint32_t chunk_offset = 0, chunk_length = 0, length_remaining = 0;
	auto rc = decode_nsm_install_token_req(msg, buf.size(), &chunk_offset,
					       &chunk_length, &length_remaining,
					       nullptr);
	EXPECT_EQ(rc, NSM_SW_ERROR_LENGTH);
}

// L591 FALSE: data=NULL, valid data_size=13, chunk_length=1 → skip copy
TEST(DebugTokenBranches, DecodeInstallTokenReq_NullData)
{
	std::vector<uint8_t> buf(
	    sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req) + 10, 0);
	// data_size=13: passes L577 (>= 13)
	buf[sizeof(nsm_msg_hdr) + 2] = 13;
	buf[sizeof(nsm_msg_hdr) + 3] = 0;
	// chunk_length=1: expected_size = 4+4+4+1 = 13 = data_size → passes
	// L588
	buf[sizeof(nsm_msg_hdr) + 10] = 1;
	auto *msg = reinterpret_cast<const nsm_msg *>(buf.data());
	uint32_t chunk_offset = 0, chunk_length = 0, length_remaining = 0;
	// data=NULL → L591 FALSE → skip copy → NSM_SW_SUCCESS
	auto rc = decode_nsm_install_token_req(msg, buf.size(), &chunk_offset,
					       &chunk_length, &length_remaining,
					       nullptr);
	EXPECT_EQ(rc, NSM_SW_SUCCESS);
}

// ---------------------------------------------------------------------------
// Buffer-overflow guard regression (nvbug 6232725): each decoder must reject
// a message whose on-wire payload length exceeds the bytes actually present
// in msg_len, returning NSM_SW_ERROR_LENGTH instead of an out-of-bounds copy.
// ---------------------------------------------------------------------------

namespace
{
// Payload offset of the data_size field inside struct nsm_common_resp
// (command:1, completion_code:1, reserved:2, data_size:2).
constexpr size_t kRespDataSizeOff = sizeof(nsm_msg_hdr) + 4;

void putU16(std::vector<uint8_t> &buf, size_t off, uint16_t v)
{
	buf[off] = static_cast<uint8_t>(v & 0xFF);
	buf[off + 1] = static_cast<uint8_t>((v >> 8) & 0xFF);
}

void putU32(std::vector<uint8_t> &buf, size_t off, uint32_t v)
{
	buf[off] = static_cast<uint8_t>(v & 0xFF);
	buf[off + 1] = static_cast<uint8_t>((v >> 8) & 0xFF);
	buf[off + 2] = static_cast<uint8_t>((v >> 16) & 0xFF);
	buf[off + 3] = static_cast<uint8_t>((v >> 24) & 0xFF);
}

std::vector<uint8_t> oversizedResp(size_t structSize, uint16_t dataSize)
{
	std::vector<uint8_t> buf(sizeof(nsm_msg_hdr) + structSize, 0);
	putU16(buf, kRespDataSizeOff, dataSize);
	return buf;
}

const nsm_msg *asMsg(const std::vector<uint8_t> &buf)
{
	return reinterpret_cast<const nsm_msg *>(buf.data());
}
} // namespace

TEST(LibnsmOverreadGuard, ProvideTokenReqValidStillDecodes)
{
	// The min-length check already guarantees the full token buffer is
	// present, so the guard must never reject a well-formed request
	// (no false positive).
	std::vector<uint8_t> buf(
	    sizeof(nsm_msg_hdr) + sizeof(nsm_provide_token_req), 0);
	auto *msg = reinterpret_cast<nsm_msg *>(buf.data());
	std::vector<uint8_t> token(32, 0xAB);
	ASSERT_EQ(
	    encode_nsm_provide_token_req(
		0, token.data(), static_cast<uint16_t>(token.size()), msg),
	    NSM_SW_SUCCESS);
	std::vector<uint8_t> out(NSM_DEBUG_TOKEN_DATA_MAX_SIZE, 0);
	uint8_t outLen = 0;
	EXPECT_EQ(
	    decode_nsm_provide_token_req(msg, buf.size(), out.data(), &outLen),
	    NSM_SW_SUCCESS);
	EXPECT_EQ(outLen, 32);
}

TEST(LibnsmOverreadGuard, ProvideTokenReqRejectsShortMessage)
{
	// nsm_provide_token_req carries a fixed-size token_data array, so the
	// minimum-length check already mandates the full buffer; an
	// over-declared length is therefore unreachable. A truncated message
	// (smaller than the required fixed layout) must still be rejected with
	// NSM_SW_ERROR_LENGTH rather than read out of bounds.
	std::vector<uint8_t> buf(
	    sizeof(nsm_msg_hdr) + sizeof(nsm_common_req_v2), 0);
	uint8_t token[8] = {0};
	uint8_t tokenLen = 0;
	EXPECT_EQ(decode_nsm_provide_token_req(asMsg(buf), buf.size(), token,
					       &tokenLen),
		  NSM_SW_ERROR_LENGTH);
}

TEST(LibnsmOverreadGuard, QueryDeviceIdsResp)
{
	auto buf = oversizedResp(sizeof(nsm_query_device_ids_resp), 0xFFFF);
	uint8_t cc = 0xFF;
	uint16_t rc = 0;
	uint8_t id[8] = {0};
	size_t idLen = 0;
	EXPECT_EQ(decode_nsm_query_device_ids_resp(asMsg(buf), buf.size(), &cc,
						   &rc, id, &idLen),
		  NSM_SW_ERROR_LENGTH);
}

TEST(LibnsmOverreadGuard, InstallTokenReq)
{
	// nsm_install_token_req: common_req_v2(6) + chunk_offset(4) +
	// chunk_length(4) + length_remaining(4) + data[1]. Keep
	// hdr.data_size consistent with chunk_length so the consistency
	// check passes and the new guard is what fires.
	std::vector<uint8_t> buf(
	    sizeof(nsm_msg_hdr) + sizeof(nsm_install_token_req), 0);
	putU16(buf, sizeof(nsm_msg_hdr) + 2, 1012);  // hdr.data_size
	putU32(buf, sizeof(nsm_msg_hdr) + 10, 1000); // chunk_length
	uint32_t off = 0;
	uint32_t len = 0;
	uint32_t rem = 0;
	uint8_t data[8] = {0};
	EXPECT_EQ(decode_nsm_install_token_req(asMsg(buf), buf.size(), &off,
					       &len, &rem, data),
		  NSM_SW_ERROR_LENGTH);
}

TEST(LibnsmOverreadGuard, QueryTokenResp)
{
	auto buf = oversizedResp(sizeof(nsm_query_token_resp), 0xFFFF);
	uint8_t cc = 0xFF;
	uint16_t rc = 0;
	uint8_t tlv[8] = {0};
	size_t tlvLen = 0;
	EXPECT_EQ(decode_nsm_query_token_resp(asMsg(buf), buf.size(), &cc, &rc,
					      tlv, &tlvLen),
		  NSM_SW_ERROR_LENGTH);
}
