// Copyright 2021 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 <flashupdate/config.hpp>
#include <nlohmann/json.hpp>
#include <stdplus/gtest/tmp.hpp>

#include <fstream>
#include <string>

#include <gtest/gtest.h>

namespace flashupdate
{

class ConfigTest : public stdplus::gtest::TestWithTmp
{};

TEST_F(ConfigTest, EmptyConfig)
{
    std::ofstream testfile;
    std::string emptyFilename = CaseTmpDir() + "/empty.json";
    testfile.open(emptyFilename, std::ios::out);
    auto empty = R"({})"_json;
    testfile << empty.dump();
    testfile.flush();

    EXPECT_THROW(createConfig(emptyFilename, 0),
                 nlohmann::detail::out_of_range);
}

TEST_F(ConfigTest, ValidConfigWithMissingPirmaryMuxSelect)
{
    std::ofstream testfile;
    std::string missingPrimaryMuxFilename =
        CaseTmpDir() + "/missing_primary_mux.json";
    testfile.open(missingPrimaryMuxFilename, std::ios::out);
    auto valid = R"(
        {
            "flash": {
                "validation_key": ["prod.pem", "dev.pem"],
                "primary": {
                    "location": "mtd,primary",
                    "mux_select": null
                },
                "secondary": [
                    {
                        "location": "mtd,secondary0",
                        "mux_select": null
                    }
                ],
                "device_id": "device_id",
                "driver": "/tmp/driver"
            },
            "metadata": {
                "path": "fake,type=simple,erase=0,metadata",
                "offset": 0
            },
            "cr51": null
        }
    )"_json;
    testfile << valid.dump();
    testfile.flush();

    EXPECT_THROW(createConfig(missingPrimaryMuxFilename, 0),
                 std::runtime_error);
}

TEST_F(ConfigTest, ValidConfigWithMissingCR51Property)
{
    std::ofstream testfile;
    std::string missingCr51Filename = CaseTmpDir() + "/missing_cr51.json";
    testfile.open(missingCr51Filename, std::ios::out);
    auto valid = R"(
        {
            "flash": {
                "validation_key": ["prod.pem", "dev.pem"],
                "primary": {
                    "location": "mtd,primary",
                    "mux_select": null
                },
                "secondary": [
                    {
                        "location": "mtd,secondary0",
                        "mux_select": null
                    }
                ],
                "device_id": "device_id",
                "driver": "/tmp/driver"
            },
            "metadata": {
                "path": "fake,type=simple,erase=0,metadata",
                "offset": 0
            },
            "cr51": {
                "prod_to_dev": false,
                "image_family": 3
            }
        }
    )"_json;
    testfile << valid.dump();
    testfile.flush();

    EXPECT_THROW(createConfig(missingCr51Filename, 0), std::runtime_error);
}

TEST_F(ConfigTest, ValidConfig)
{
    std::ofstream testfile;
    std::string validFilename = CaseTmpDir() + "/valid.json";
    // Example, validFilename should be /tmp/valid.json
    //   name = "valid"
    //   configPath = CaseTmpDir()
    std::string configPath = CaseTmpDir() + "/";
    size_t index = configPath.size(); // /tmp/
    std::string name =
        validFilename.substr(index, validFilename.size() - index - /*.json*/ 5);
    testfile.open(validFilename, std::ios::out);
    auto valid = R"(
        {
            "flash": {
                "validation_key": ["prod.pem", "dev.pem"],
                "primary": {
                    "location": "mtd,primary",
                    "mux_select": 1
                },
                "secondary": [
                    {
                        "location": "mtd,secondary0",
                        "mux_select": null
                    },
                    {
                        "location": "mtd,secondary1",
                        "mux_select": 2
                    }
                ],
                "device_id": "device_id",
                "driver": "/tmp/driver"
            },
            "metadata": {
                "path": "fake,type=simple,erase=0,metadata",
                "offset": 128
            },
            "cr51": {
                "prod_to_dev": false,
                "production_mode": true,
                "unsigned_to_dev": true,
                "image_family": 3
            },
            "supported_version": [{
                "min": {
                    "major": 10,
                    "minor": 10,
                    "point": 10,
                    "subpoint": 10
                }
            },
            {
                "max": {
                    "major": 10,
                    "minor": 10,
                    "point": 10,
                    "subpoint": 10
                }
            }]
        }
    )"_json;
    testfile << valid.dump();
    testfile.flush();
    std::vector<std::string> expectedKey = {"prod.pem", "dev.pem"};

    // Test auto config finding with wrong path
    EXPECT_THROW(createConfig(name, 0, "/bad/"), std::runtime_error);

    // Test Invalid secondary index
    // secondary index > count(secondaries)
    EXPECT_THROW(createConfig(validFilename, 3), std::runtime_error);

    // Test Validate Json Config
    auto config = createConfig(validFilename, 1);

    // Test auto config finding
    auto config1 = createConfig(name, 1, configPath);
    EXPECT_EQ(config, config1);

    // BIOS
    EXPECT_EQ(config.flash.deviceId, "device_id");
    EXPECT_EQ(config.flash.driver, "/tmp/driver");
    EXPECT_EQ(config.flash.stagingIndex, 1);

    // BIOS Public Key
    EXPECT_TRUE(config.flash.validationKey == expectedKey);

    // BIOS Primary
    EXPECT_EQ(config.flash.primary.location, "mtd,primary");
    EXPECT_EQ(config.flash.primary.muxSelect, 1);

    // BIOS Secondary
    ASSERT_EQ(config.flash.secondary.size(), 2);
    EXPECT_EQ(config.flash.secondary[0].location, "mtd,secondary0");
    EXPECT_EQ(config.flash.secondary[0].muxSelect, std::nullopt);
    EXPECT_EQ(config.flash.secondary[1].location, "mtd,secondary1");
    EXPECT_EQ(config.flash.secondary[1].muxSelect, 2);

    // METADATA
    EXPECT_EQ(config.metadata.offset, 128);
    EXPECT_EQ(config.metadata.path, "fake,type=simple,erase=0,metadata");

    // CR51 Config
    EXPECT_EQ(config.cr51->imageFamily, 3);
    EXPECT_FALSE(config.cr51->prodToDev);
    EXPECT_TRUE(config.cr51->productionMode);
    EXPECT_TRUE(config.cr51->unsignedToDev);

    // CR51 Config
    std::string versionStr = "10.10.10.10";
    auto version = version::Version(versionStr);
    ASSERT_NE(config.supportedVersion, std::nullopt);
    ASSERT_EQ(config.supportedVersion->size(), 2);
    EXPECT_EQ((*config.supportedVersion)[0].min, version);
    EXPECT_EQ((*config.supportedVersion)[0].max, std::nullopt);
    EXPECT_EQ((*config.supportedVersion)[1].min, std::nullopt);
    EXPECT_EQ((*config.supportedVersion)[1].max, version);
}

} // namespace flashupdate
