/*
* Copyright (c), Huawei Technologies Co., Ltd. 2025-2025.All rights reserved.
 */

#include <gtest/gtest.h>
#include "TestUtil.h"
#include "Util/ScalaryProtocolUtil.h"
#include "LineOpFactory.h"
using namespace Insight::Scalar::Smoothing;
namespace Insight::UnitTest {
class LineOpTest : public ::testing::Test
{
protected:
    static void SetUpTestSuite()
    {
        auto file1 = ScalarVisuallyServer::Instance().AddFile("file1");
        auto file2 = ScalarVisuallyServer::Instance().AddFile("file2");
        ScalarVisuallyServer::Instance().UpdateGraph("train", "file1", GenerateRandomData({0, 100}, {0, 1}));
        ScalarVisuallyServer::Instance().UpdateGraph("train", "file2", GenerateRandomData({100, 200}, {2, 3}) );
    }

    static void TearDownTestSuite()
    {
        ScalarVisuallyServer::Instance().DelFile("file1");
        ScalarVisuallyServer::Instance().DelFile("file2");
    }

};

TEST_F(LineOpTest, BuildLineOp)
{
    std::string jsonStr = R"({                 {
                     "type":"normal"
                 },
                 {
                     "type": "token",
                     "enable": true,
                     "globalBatchSize": 0.0,
                     "seqLength":0.0
                 },
                 {
                     "type":"smoothing",
                     "enable": true,
                     "algorithm":"windowMedian",
                     "windowSize": 20,
                 },)";
    auto param = ParseJsonToStr(jsonStr);
    LineBasicInfo info{"train", "test", 0, std::numeric_limits<uint64_t>::max()};
    std::unordered_map<LineType, std::shared_ptr<LineOp>> opsMap;
    BuildLineOps(param, info, opsMap);
    EXPECT_NE(opsMap.find(LineType::NORMAL), opsMap.end());
    EXPECT_NE(opsMap.find(LineType::TOKEN), opsMap.end());
    EXPECT_NE(opsMap.find(LineType::SMOOTHING), opsMap.end());
}

TEST_F(LineOpTest, NormalLineOp)
{
    auto op = std::make_shared<NormalLineOp>();
    constexpr int64_t right = 50;
    op->SetBasicInfo("train", "file1", 0, right);
    std::vector<LineData> graphLine;
    op->Process(graphLine);
    EXPECT_EQ(graphLine.size(), 1);
    auto data = graphLine[0].GetElements();
    EXPECT_EQ(ScalarPointsCheck(data, {0, right}, {0, 1}), true);
}

TEST_F(LineOpTest, SmoothingLineOp)
{
    constexpr int64_t right = 50;
    auto op = std::make_shared<SmoothingLineOp>();
    op->SetBasicInfo("train", "file1", 0, right);
    op->SetSmoothingParam("windowMedain", std::make_unique<WindowMedianParam>());
    std::vector<LineData> graphLine;
    op->Process(graphLine);
    EXPECT_EQ(graphLine.size(), 1);
    auto data = graphLine[0].GetElements();
    EXPECT_EQ(ScalarPointsCheck(data, {0, right}, {0, 1}), true);
}

TEST_F(LineOpTest, TokenLineOp)
{
    constexpr int64_t right = 50;
    auto op = std::make_shared<NormalLineOp>();
    op->SetBasicInfo("train", "file1", 0, right);
    std::vector<LineData> graphLine;
    op->Process(graphLine);
    auto op1 = std::make_shared<TokenLineOp>();
    op1->SetBasicInfo("train", "file1", 0, right);
    auto file = ScalarVisuallyServer::Instance().GetFileInfo("file1");
    constexpr uint64_t expectSize = 100;
    file->UpdateTokenParam(expectSize, expectSize);
    op1->Process(graphLine);
    EXPECT_EQ(graphLine.size(), 1);
    auto data = graphLine[0].GetElements();
    EXPECT_EQ(ScalarPointsCheck(data, {0, right * 10}, {0, 1}), true);
}

TEST_F(LineOpTest, SampleLineOp)
{
    auto file = ScalarVisuallyServer::Instance().AddFile("file3");
    ScalarVisuallyServer::Instance().UpdateGraph("train", "file3",GenerateRandomData({0, 30000}, {0,2}));
    auto op = std::make_shared<NormalLineOp>();
    op->SetBasicInfo("train", "file3", 0, std::numeric_limits<std::uint64_t>::max());
    std::vector<LineData> graphLine;
    op->Process(graphLine);
    auto op2 = std::make_shared<SampleLineOp>();
    op2->Process(graphLine);
    EXPECT_EQ(graphLine.size(), 1);
    auto data = graphLine[0].GetElements();
    constexpr uint64_t expectSize = 10002;
    EXPECT_EQ(data.size(), expectSize);
}
}