/**
 * Copyright (C) 2017 IBM Corporation
 *
 * 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 "registration.hpp"
#include "targeting.hpp"

#include <stdlib.h>

#include <experimental/filesystem>
#include <fstream>

#include <gtest/gtest.h>

using namespace openpower::util;
using namespace openpower::targeting;
namespace fs = std::experimental::filesystem;

ProcedureMap Registration::procedures;

constexpr auto masterDir = "/tmp";

class TargetingTest : public ::testing::Test
{
  protected:
    virtual void SetUp()
    {
        char dir[50];
        strcpy(dir, masterDir);
        strcat(dir, "/targetingXXXXXX");

        auto path = mkdtemp(dir);
        assert(path != nullptr);

        _slaveBaseDir = path;

        _slaveDir = _slaveBaseDir / "fsi1";
        fs::create_directory(_slaveDir);
    }

    virtual void TearDown()
    {
        fs::remove_all(_slaveDir);
        fs::remove_all(_slaveBaseDir);
    }

    fs::path _slaveBaseDir;
    fs::path _slaveDir;
};

TEST_F(TargetingTest, CreateTargets)
{

    // Test that we always create the first Target
    {
        Targeting targets{masterDir, _slaveDir};
        ASSERT_EQ(targets.size(), 1);

        auto t = targets.begin();
        ASSERT_EQ((*t)->getPos(), 0);

        ASSERT_EQ((*t)->getCFAMPath(), masterDir);
    }

    // Test that we can create multiple Targets
    {
        // make some fake slave entries
        std::ofstream(_slaveDir / "slave@01:00");
        std::ofstream(_slaveDir / "slave@02:00");
        std::ofstream(_slaveDir / "slave@03:00");
        std::ofstream(_slaveDir / "slave@04:00");

        Targeting targets{masterDir, _slaveDir};

        ASSERT_EQ(targets.size(), 5);

        int i = 0;

        for (const auto& t : targets)
        {
            fs::path path;

            ASSERT_EQ(t->getPos(), i);

            if (0 == i)
            {
                path = masterDir;
            }
            else
            {
                std::ostringstream subdir;
                subdir << "slave@0" << i << ":00/raw";

                path = _slaveDir;
                path /= subdir.str();
            }

            ASSERT_EQ(t->getCFAMPath(), path);
            i++;
        }
    }
}

void func1()
{
    std::cout << "Hello\n";
}

void func2()
{
    std::cout << "World\n";
}

REGISTER_PROCEDURE("hello", func1);
REGISTER_PROCEDURE("world", func2);

TEST(RegistrationTest, TestReg)
{
    int count = 0;
    for (const auto& p : Registration::getProcedures())
    {
        std::cout << p.first << std::endl;
        p.second();
        count++;
    }

    ASSERT_EQ(count, 2);
}
