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

#include <flashupdate/flash.hpp>
#include <flashupdate/flash/mock.hpp>
#include <stdplus/gtest/tmp.hpp>

#include <format>
#include <fstream>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

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

namespace flashupdate
{

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

TEST_F(FlashHelperTest, readMtdFileNoData)
{
    flash::FlashHelper flashHepler;

    std::string filename = CaseTmpDir() + "/test_no_data.txt";
    std::ofstream testfile;

    testfile.open(filename.data(), std::ios::out);
    testfile << "";
    testfile.flush();
    EXPECT_THROW(
        try {
            flashHepler.readMtdFileText(filename);
        } catch (const std::runtime_error& e) {
            EXPECT_STREQ("not able to find newline in the mtd file", e.what());
            throw;
        },
        std::runtime_error);
    testfile.close();
}

TEST_F(FlashHelperTest, readMtdFileNoNewLine)
{
    flash::FlashHelper flashHepler;
    std::string filename = CaseTmpDir() + "/test_no_newline.txt";
    std::ofstream testfile;
    std::vector<std::string_view> tests = {
        "test",
        "1123213s  asd",
        "  4234",
        "      ",
    };

    for (const auto& test : tests)
    {
        testfile.open(filename.data(), std::ios::out);
        testfile << test.data();
        testfile.flush();
        EXPECT_THROW(
            try {
                flashHepler.readMtdFileText(filename);
            } catch (const std::runtime_error& e) {
                EXPECT_STREQ("not able to find newline in the mtd file",
                             e.what());
                throw;
            },
            std::runtime_error);
        testfile.close();
    }
}

TEST_F(FlashHelperTest, readMtdFilePass)
{
    flash::FlashHelper flashHepler;
    std::string filename = CaseTmpDir() + "/test_pass.txt";
    std::ofstream testfile;
    std::vector<std::pair<std::string_view, std::string_view>> tests = {
        {"1234SS       \n      ", "1234SS       "},
        {"hello world\n", "hello world"},
        {"  xyz@@   \n      ", "  xyz@@   "},
        {"yes\n  dds  \n  ", "yes"},
        {"4123\n  dds ", "4123"},
        {"\n", ""},
    };

    for (const auto& test : tests)
    {
        testfile.open(filename.data(), std::ios::out);
        testfile << test.first.data();
        testfile.flush();
        EXPECT_EQ(flashHepler.readMtdFileText(filename), test.second.data());
        testfile.close();
    }
}

class FlashTest : public ::testing::Test
{
  protected:
    FlashTest()
    {
        Config config;

        std::string dev("mtd,/dev/primary-flash");
        config.flash.primary = Config::Partition{
            primaryDevReq,
            std::nullopt,
        };

        config.flash.stagingIndex = 1;

        config.flash.secondary = {
            Config::Partition(),
            Config::Partition{
                secondaryDevReq,
                1,
            },
        };
        flash = flash::Flash(config, false);
        flash.setFlashHelper(&flashHelper);
    }

    flash::Flash flash;
    std::string primaryDevReq = "mtd,primary-flash";
    std::string primaryDev = "mtd,/dev/mtd9";
    std::string secondaryDevReq = "mtd,secondary-flash";
    std::string secondaryDev = "mtd,/dev/mtd10";
    flash::MockHelper flashHelper;
};

TEST_F(FlashTest, getFlashPrimaryMtd)
{
    std::string expectedName("primary-flash");
    std::string expectedDev("mtd9");
    uint32_t expectedSize(324);

    EXPECT_CALL(flashHelper, findMtdDevice(expectedName))
        .WillOnce(Return(expectedDev));
    EXPECT_CALL(
        flashHelper,
        readMtdFileText(std::format("/sys/class/mtd/{}/size", expectedDev)))
        .WillOnce(Return(std::to_string(expectedSize)));

    EXPECT_EQ(flash.getFlash(/*primary=*/true),
              std::make_pair(primaryDev, expectedSize));
}

TEST_F(FlashTest, getFlashSecondaryMtd)
{
    std::string expectedName("secondary-flash");
    std::string expectedDev("mtd10");
    uint32_t expectedSize(1234);

    EXPECT_CALL(flashHelper, findMtdDevice(expectedName))
        .WillOnce(Return(expectedDev));
    EXPECT_CALL(
        flashHelper,
        readMtdFileText(std::format("/sys/class/mtd/{}/size", expectedDev)))
        .WillOnce(Return(std::to_string(expectedSize)));

    EXPECT_EQ(flash.getFlash(/*primary=*/false),
              std::make_pair(secondaryDev, expectedSize));
}

TEST_F(FlashTest, getFlashMtdNameNotMatch)
{
    EXPECT_CALL(flashHelper, findMtdDevice(std::string("secondary-flash")))
        .WillOnce(Return(""));
    EXPECT_CALL(flashHelper, findMtdDevice(std::string("primary-flash")))
        .WillOnce(Return(""));

    EXPECT_EQ(flash.getFlash(/*primary=*/false), std::nullopt);
    EXPECT_EQ(flash.getFlash(/*primary=*/true), std::nullopt);
}

} // namespace flashupdate
