#include <attn/attention.hpp>
#include <attn/attn_common.hpp>
#include <attn/attn_config.hpp>
#include <attn/attn_handler.hpp>
#include <util/pdbg.hpp>
#include <util/trace.hpp>

#include "gtest/gtest.h"

namespace attn
{
// these are in the attn_lib but not all exposed via headers
int handleSpecial(Attention* i_attention);
} // namespace attn

using namespace attn;
using namespace util::pdbg;

/** @brief global function to be called back. */
int handleAttention(Attention* attention)
{
    int rc = RC_SUCCESS;
    if (attention != nullptr)
    {
        return rc;
    }
    else
    {
        return RC_NOT_HANDLED;
    }
}

// Global variables for UT #1 and UT#2.
// Attention type
Attention::AttentionType gType = Attention::AttentionType::Special;
// pointer to handler callback function
int (*gHandler)(Attention*)   = &(handleSpecial);
const AttentionFlag gAttnFlag = AttentionFlag::enBreakpoints;

// Start preparation for UT case #1.

// Global variables for UT #1
const char* gPosPath = "/proc0/pib/perv12";
const uint32_t gPos  = 12;

/** @brief Fixture class for TEST_F(). */
class AttentionTestPos : public testing::Test
{
  public:
    AttentionTestPos() {}

    void SetUp()
    {
        pdbg_targets_init(nullptr);

        target = pdbg_target_from_path(nullptr, gPosPath);
        EXPECT_NE(nullptr, target);

        config = new Config;
        EXPECT_EQ(true, config->getFlag(gAttnFlag));

        pAttn = std::make_unique<Attention>(
            Attention(gType, gHandler, target, config));
    }

    void TearDown()
    {
        delete config;
    }

    std::unique_ptr<Attention> pAttn;
    Config* config;
    pdbg_target* target = nullptr;
};

TEST_F(AttentionTestPos, TestAttnTargetPos)
{
    EXPECT_EQ(0, pAttn->getPriority());
    EXPECT_EQ(RC_SUCCESS, pAttn->handle());

    // Verify the global target_tmp.
    EXPECT_NE(nullptr, target);
    uint32_t attr = std::numeric_limits<uint32_t>::max();
    pdbg_target_get_attribute(target, "ATTR_FAPI_POS", 4, 1, &attr);
    EXPECT_EQ(gPos, attr);

    // Verify the target in Attention object.
    attr                    = std::numeric_limits<uint32_t>::max();
    pdbg_target* target_tmp = pAttn->getTarget();
    EXPECT_NE(nullptr, target_tmp);
    pdbg_target_get_attribute(target_tmp, "ATTR_FAPI_POS", 4, 1, &attr);
    EXPECT_EQ(gPos, attr);

    // Verify the config in Attention object.
    Config* config_tmp = pAttn->getConfig();
    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
    config_tmp->clearFlag(gAttnFlag);
    EXPECT_EQ(false, config_tmp->getFlag(gAttnFlag));
    config_tmp->setFlag(gAttnFlag);
    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
}

// Start preparation for UT case #2.

// Global variables for UT #2
const uint32_t gChipId = 0; // ID for proc0.

/** @brief Fixture class for TEST_F(). */
class AttentionTestProc : public testing::Test
{
  public:
    AttentionTestProc() {}

    void SetUp()
    {
        pdbg_targets_init(nullptr);
        target = getPrimaryProcessor();

        EXPECT_NE(nullptr, target);

        attr = std::numeric_limits<uint32_t>::max();
        attr = getTrgtType(target);

        EXPECT_EQ(TYPE_PROC, attr);

        attr = std::numeric_limits<uint32_t>::max();
        pdbg_target_get_attribute(target, "ATTR_CHIP_ID", 4, 1, &attr);
        EXPECT_EQ(attr, gChipId);

        config = new Config;
        EXPECT_EQ(true, config->getFlag(gAttnFlag));

        pAttn = std::make_unique<Attention>(
            Attention(gType, gHandler, target, config));
    }

    void TearDown()
    {
        delete config;
    }

    std::unique_ptr<Attention> pAttn;
    Config* config;
    pdbg_target* target = nullptr;
    uint32_t attr;
};

TEST_F(AttentionTestProc, TestAttentionProc)
{
    EXPECT_EQ(0, pAttn->getPriority());
    EXPECT_EQ(RC_SUCCESS, pAttn->handle());

    // Verify the target in Attention object.
    attr                    = std::numeric_limits<uint32_t>::max();
    pdbg_target* target_tmp = pAttn->getTarget();
    EXPECT_NE(nullptr, target_tmp);
    attr = getTrgtType(target_tmp);
    EXPECT_EQ(TYPE_PROC, attr);

    attr = std::numeric_limits<uint32_t>::max();
    pdbg_target_get_attribute(target_tmp, "ATTR_CHIP_ID", 4, 1, &attr);
    EXPECT_EQ(attr, gChipId);

    // Verify the config in Attention object.
    Config* config_tmp = pAttn->getConfig();
    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
    config_tmp->clearFlag(gAttnFlag);
    EXPECT_EQ(false, config_tmp->getFlag(gAttnFlag));
    config_tmp->setFlag(gAttnFlag);
    EXPECT_EQ(true, config_tmp->getFlag(gAttnFlag));
}