/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved.
 * KubernetesPlugin is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#include "test_shm_task_executor.h"
using namespace shm::task_executor;
using namespace testing;

namespace shm::ut {

void TestTaskExecutor::SetUp()
{
    Test::SetUp();
    executorPtr = ShmTaskExecutor::Create(THREAD_NUM, QUEUE_CAPACITY);
}

void TestTaskExecutor::TearDown()
{
    Test::TearDown();
}

TEST_F(TestTaskExecutor, testCreateTaskExecutorSucess)
{
    EXPECT_TRUE(executorPtr != nullptr);
}

TEST_F(TestTaskExecutor, testCreateTaskExecutorFail)
{
    auto testExecutor = ShmTaskExecutor::Create(0, QUEUE_CAPACITY);
    EXPECT_EQ(testExecutor, nullptr);
}

TEST_F(TestTaskExecutor, testExecutorStart)
{
    auto ret = executorPtr->Start();
    EXPECT_TRUE(ret);
}

TEST_F(TestTaskExecutor, testExecutorStartTwice)
{
    auto ret = executorPtr->Start();
    ret = executorPtr->Start();
    EXPECT_TRUE(ret);
}

TEST_F(TestTaskExecutor, testExecutorQueueInitFailed)
{
    MOCKER(&shm::utils::RingBufferBlockingQueue<ShmRunnable *>::Initialize).stubs().will(returnValue(-1));
    auto ret = executorPtr->Start();
    EXPECT_FALSE(ret);
    MOCKER(&shm::utils::RingBufferBlockingQueue<ShmRunnable *>::Initialize).reset();
}

TEST_F(TestTaskExecutor, testExecutorExecut)
{
    auto ret = executorPtr->Start();
    EXPECT_TRUE(ret);
    auto testShmRunnablePtr = new TestShmRunnable();
    executorPtr->Execute(testShmRunnablePtr);
    while (testShmRunnablePtr->testData.empty()) {
        sleep(1);
    }
    EXPECT_EQ(RUN_SUCCESS, testShmRunnablePtr->testData);
}

TEST_F(TestTaskExecutor, testExecutorExecutUseLambda)
{
    auto ret = executorPtr->Start();
    EXPECT_TRUE(ret);
    std::string testData = "ERROR";
    executorPtr->Execute([&testData]() { testData = RUN_SUCCESS; });
    while (testData == "ERROR") {
        sleep(1);
    }
    EXPECT_EQ(RUN_SUCCESS, testData);
}

TEST_F(TestTaskExecutor, testExecutorStop)
{
    auto ret = executorPtr->Start();
    EXPECT_TRUE(ret);
    executorPtr->Stop();
    EXPECT_EQ(executorPtr->mStopped, true);
}

TEST_F(TestTaskExecutor, testExecutorStopCreateShmRunnableFailed)
{
    auto ret = executorPtr->Start();
    EXPECT_TRUE(ret);
    MOCKER(&ShmRunnable::GetRef).stubs().will(returnValue(nullptr));
    executorPtr->Stop();
    EXPECT_EQ(executorPtr->mStopped, true);
    MOCKER(&ShmRunnable::GetRef).reset();
}

TEST_F(TestTaskExecutor, testExecutorExecutWhenStop)
{
    auto ret = executorPtr->Start();
    EXPECT_TRUE(ret);
    executorPtr->Stop();
    auto testShmRunnablePtr = new TestShmRunnable();
    executorPtr->Execute(testShmRunnablePtr);
    executorPtr->Stop();
    EXPECT_NE(RUN_SUCCESS, testShmRunnablePtr->testData);
}

TEST_F(TestTaskExecutor, testExecutorThreadNameModify)
{
    auto ret = executorPtr->Start();
    EXPECT_TRUE(ret);
    executorPtr->SetThreadName(THREAD_NAME);
    EXPECT_EQ(executorPtr->mThreadName, THREAD_NAME);
}

} // namespace shm::ut