// Copyright 2025 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 <flasher/file/memory.hpp>
#include <flashupdate/validator/cr51.hpp>

#include <memory>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;

namespace google::cr51
{

// Mock for the Cr51SignValidator dependency
class MockCr51SignValidator : public Cr51SignValidator
{
  public:
    MOCK_METHOD(std::span<const uint8_t>, hashDescriptor,
                (struct libcr51sign_ctx*, std::span<std::byte>), (override));
    MOCK_METHOD(std::optional<struct libcr51sign_validated_regions>,
                validateDescriptor, (struct libcr51sign_ctx*, bool),
                (override));
    MOCK_METHOD(bool, isBiosKeyRotationSupport, (), (override));
    MOCK_METHOD(bool, isDevSignedImageAllowed, (), (override));
};

} // namespace google::cr51

namespace flashupdate::validator::cr51
{

class Cr51VerifyTest : public ::testing::Test
{
  protected:
    Cr51VerifyTest() :
        cr51ValidatorMock(
            std::make_unique<
                ::testing::StrictMock<google::cr51::MockCr51SignValidator>>()),
        cr51(*cr51ValidatorMock)
    {
        // Provide some dummy data for the reader
        std::vector<std::byte> imageData(1024, std::byte{0});
        reader.writeAtExact(imageData, 0);
    }

    flasher::file::Memory reader;
    const std::vector<std::string> fallbackKeys = {"key1.pem", "key2.pem"};
    std::unique_ptr<google::cr51::MockCr51SignValidator> cr51ValidatorMock;
    Cr51 cr51;
};

TEST_F(Cr51VerifyTest, RoTSupported_ValidationSucceeds)
{
    EXPECT_CALL(*cr51ValidatorMock, isBiosKeyRotationSupport())
        .WillOnce(Return(true));

    // Neither of these should be called if RoT validation succeeds.
    EXPECT_CALL(*cr51ValidatorMock, isDevSignedImageAllowed()).Times(0);
    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, false)).Times(0);

    auto successfulValidation = [](libcr51sign_ctx* ctx, bool /*useRoT*/) {
        ctx->descriptor.descriptor_offset = 0;
        ctx->descriptor.descriptor_area_size = 128;
        ctx->descriptor.image_major = 1;
        ctx->descriptor.image_minor = 2;
        ctx->descriptor.image_point = 3;
        ctx->descriptor.image_subpoint = 4;
        ctx->descriptor.hash_type = HASH_SHA2_256;
        return libcr51sign_validated_regions{};
    };

    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, true))
        .WillOnce(Invoke(successfulValidation));
    EXPECT_CALL(*cr51ValidatorMock, hashDescriptor(_, _))
        .WillOnce(Return(std::span<const uint8_t>{}));
    EXPECT_TRUE(cr51.validateImage(reader, fallbackKeys));
}

TEST_F(Cr51VerifyTest, RoTSupported_RoTValidationFails_AndDevNotAllowed)
{
    EXPECT_CALL(*cr51ValidatorMock, isBiosKeyRotationSupport())
        .WillOnce(Return(true));
    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, true))
        .WillOnce(Return(std::nullopt));
    EXPECT_CALL(*cr51ValidatorMock, isDevSignedImageAllowed())
        .WillOnce(Return(false));
    // Fallback validation should not be called.
    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, false)).Times(0);
    EXPECT_FALSE(cr51.validateImage(reader, fallbackKeys));
}

TEST_F(Cr51VerifyTest,
       RoTSupported_RoTValidationFails_DevAllowed_FallbackSucceeds)
{
    EXPECT_CALL(*cr51ValidatorMock, isBiosKeyRotationSupport())
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, true))
        .WillOnce(Return(std::nullopt));
    EXPECT_CALL(*cr51ValidatorMock, isDevSignedImageAllowed())
        .WillOnce(Return(true));

    auto successfulValidation = [](libcr51sign_ctx* ctx, bool /*useRoT*/) {
        ctx->descriptor.descriptor_offset = 0;
        ctx->descriptor.descriptor_area_size = 128;
        ctx->descriptor.image_major = 1;
        ctx->descriptor.image_minor = 2;
        ctx->descriptor.image_point = 3;
        ctx->descriptor.image_subpoint = 4;
        ctx->descriptor.hash_type = HASH_SHA2_256;
        return libcr51sign_validated_regions{};
    };

    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, false))
        .WillOnce(Invoke(successfulValidation));
    EXPECT_CALL(*cr51ValidatorMock, hashDescriptor(_, _))
        .WillOnce(Return(std::span<const uint8_t>{}));
    EXPECT_TRUE(cr51.validateImage(reader, fallbackKeys));
}

TEST_F(Cr51VerifyTest, RoTSupported_RoTValidationFails_DevAllowed_FallbackFails)
{
    EXPECT_CALL(*cr51ValidatorMock, isBiosKeyRotationSupport())
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, true))
        .WillOnce(Return(std::nullopt));
    EXPECT_CALL(*cr51ValidatorMock, isDevSignedImageAllowed())
        .WillOnce(Return(true));

    // Fallback validation also fails.
    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, false))
        .Times(fallbackKeys.size())
        .WillRepeatedly(Return(std::nullopt));

    EXPECT_FALSE(cr51.validateImage(reader, fallbackKeys));
}

TEST_F(Cr51VerifyTest, RoTNotSupported_FallbackSucceeds)
{
    EXPECT_CALL(*cr51ValidatorMock, isBiosKeyRotationSupport())
        .WillRepeatedly(Return(false));
    EXPECT_CALL(*cr51ValidatorMock, isDevSignedImageAllowed()).Times(0);

    // The RoT path validateDescriptor(_, true) should not be called.
    auto successfulValidation = [](libcr51sign_ctx* ctx, bool /*useRoT*/) {
        ctx->descriptor.descriptor_offset = 0;
        ctx->descriptor.descriptor_area_size = 128;
        ctx->descriptor.image_major = 1;
        ctx->descriptor.image_minor = 2;
        ctx->descriptor.image_point = 3;
        ctx->descriptor.image_subpoint = 4;
        ctx->descriptor.hash_type = HASH_SHA2_256;
        return libcr51sign_validated_regions{};
    };

    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, false))
        .WillOnce(Invoke(successfulValidation));
    EXPECT_CALL(*cr51ValidatorMock, hashDescriptor(_, _))
        .WillOnce(Return(std::span<const uint8_t>{}));
    EXPECT_TRUE(cr51.validateImage(reader, fallbackKeys));
}

TEST_F(Cr51VerifyTest, RoTNotSupported_FallbackFails)
{
    EXPECT_CALL(*cr51ValidatorMock, isBiosKeyRotationSupport())
        .WillRepeatedly(Return(false));

    // The RoT path validateDescriptor(_, true) should not be called.
    EXPECT_CALL(*cr51ValidatorMock, validateDescriptor(_, false))
        .Times(fallbackKeys.size())
        .WillRepeatedly(Return(std::nullopt));
    EXPECT_FALSE(cr51.validateImage(reader, fallbackKeys));
}

} // namespace flashupdate::validator::cr51
