#include <iostream>
#include <stdexcept>
#include <sstream>
#include <cmath>
#include "./test_framework.hpp"

namespace lsp::test
{
    // ==================== TestRunner 实现 ====================

    void TestRunner::addTest(const std::string& name, TestFunction test)
    {
        tests.push_back({ name, test });
    }

    void TestRunner::runAllTests()
    {
        results.clear();
        std::cout << "\n========== 开始运行测试 ==========\n"
                  << std::endl;

        for (const auto& testCase : tests)
        {
            try
            {
                TestResult result = testCase.function();
                result.testName = testCase.name;
                results.push_back(result);
                printResult(result);
            }
            catch (const std::exception& e)
            {
                TestResult result;
                result.testName = testCase.name;
                result.passed = false;
                result.message = std::string("异常: ") + e.what();
                results.push_back(result);
                printResult(result);
            }
        }

        printSummary();
    }

    int TestRunner::getFailedCount() const
    {
        int count = 0;
        for (const auto& result : results)
        {
            if (!result.passed)
            {
                count++;
            }
        }
        return count;
    }

    int TestRunner::getTotalCount() const
    {
        return static_cast<int>(results.size());
    }

    void TestRunner::printResult(const TestResult& result)
    {
        if (result.passed)
        {
            std::cout << "[✓] " << result.testName << std::endl;
        }
        else
        {
            std::cout << "[✗] " << result.testName << std::endl;
            std::cout << "    失败: " << result.message << std::endl;
        }
    }

    void TestRunner::printSummary()
    {
        int passed = getTotalCount() - getFailedCount();
        int failed = getFailedCount();
        int total = getTotalCount();

        std::cout << "\n========== 测试总结 ==========\n";
        std::cout << "总计: " << total << " 个测试\n";
        std::cout << "通过: " << passed << " 个\n";
        std::cout << "失败: " << failed << " 个\n";

        if (failed == 0)
        {
            std::cout << "\n所有测试通过！ ✓\n"
                      << std::endl;
        }
        else
        {
            std::cout << "\n部分测试失败 ✗\n"
                      << std::endl;
        }
    }

    // ==================== 断言辅助函数实现 ====================

    void assertTrue(bool condition, const std::string& message)
    {
        if (!condition)
        {
            throw std::runtime_error(message);
        }
    }

    void assertFalse(bool condition, const std::string& message)
    {
        if (condition)
        {
            throw std::runtime_error(message);
        }
    }

    void assertEqual(int expected, int actual, const std::string& message)
    {
        if (expected != actual)
        {
            std::stringstream ss;
            ss << message << " (期望: " << expected << ", 实际: " << actual << ")";
            throw std::runtime_error(ss.str());
        }
    }

    void assertEqual(unsigned int expected, unsigned int actual, const std::string& message)
    {
        if (expected != actual)
        {
            std::stringstream ss;
            ss << message << " (期望: " << expected << ", 实际: " << actual << ")";
            throw std::runtime_error(ss.str());
        }
    }

    void assertEqual(double expected, double actual, const std::string& message)
    {
        if (std::abs(expected - actual) > 1e-9)
        {
            std::stringstream ss;
            ss << message << " (期望: " << expected << ", 实际: " << actual << ")";
            throw std::runtime_error(ss.str());
        }
    }

    void assertEqual(bool expected, bool actual, const std::string& message)
    {
        if (expected != actual)
        {
            std::stringstream ss;
            ss << message << " (期望: " << (expected ? "true" : "false")
               << ", 实际: " << (actual ? "true" : "false") << ")";
            throw std::runtime_error(ss.str());
        }
    }

    void assertEqual(const std::string& expected, const std::string& actual, const std::string& message)
    {
        if (expected != actual)
        {
            std::stringstream ss;
            ss << message << " (期望: \"" << expected << "\", 实际: \"" << actual << "\")";
            throw std::runtime_error(ss.str());
        }
    }

    void assertEqual(size_t expected, size_t actual, const std::string& message)
    {
        if (expected != actual)
        {
            std::stringstream ss;
            ss << message << " (期望: " << expected << ", 实际: " << actual << ")";
            throw std::runtime_error(ss.str());
        }
    }

} // namespace lsp::test
