/**
 * Copyright © 2019 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 "action.hpp"
#include "action_environment.hpp"
#include "id_map.hpp"
#include "if_action.hpp"
#include "mock_action.hpp"
#include "mock_services.hpp"

#include <exception>
#include <memory>
#include <stdexcept>
#include <utility>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace phosphor::power::regulators;

using ::testing::Return;
using ::testing::Throw;

TEST(IfActionTests, Constructor)
{
    // Test where else clause is not specified
    {
        std::unique_ptr<Action> conditionAction =
            std::make_unique<MockAction>();

        std::vector<std::unique_ptr<Action>> thenActions{};
        thenActions.push_back(std::make_unique<MockAction>());
        thenActions.push_back(std::make_unique<MockAction>());

        IfAction ifAction{std::move(conditionAction), std::move(thenActions)};
        EXPECT_NE(ifAction.getConditionAction().get(), nullptr);
        EXPECT_EQ(ifAction.getThenActions().size(), 2);
        EXPECT_EQ(ifAction.getElseActions().size(), 0);
    }

    // Test where else clause is specified
    {
        std::unique_ptr<Action> conditionAction =
            std::make_unique<MockAction>();

        std::vector<std::unique_ptr<Action>> thenActions{};
        thenActions.push_back(std::make_unique<MockAction>());
        thenActions.push_back(std::make_unique<MockAction>());

        std::vector<std::unique_ptr<Action>> elseActions{};
        elseActions.push_back(std::make_unique<MockAction>());

        IfAction ifAction{std::move(conditionAction), std::move(thenActions),
                          std::move(elseActions)};
        EXPECT_NE(ifAction.getConditionAction().get(), nullptr);
        EXPECT_EQ(ifAction.getThenActions().size(), 2);
        EXPECT_EQ(ifAction.getElseActions().size(), 1);
    }
}

TEST(IfActionTests, Execute)
{
    // Create ActionEnvironment
    IDMap idMap{};
    MockServices services{};
    ActionEnvironment env{idMap, "", services};

    // Test where action throws an exception
    try
    {
        // Create condition action that will return true
        std::unique_ptr<MockAction> conditionAction =
            std::make_unique<MockAction>();
        EXPECT_CALL(*conditionAction, execute).Times(1).WillOnce(Return(true));

        // Create vector of actions for then clause
        std::vector<std::unique_ptr<Action>> thenActions{};
        std::unique_ptr<MockAction> thenAction;

        // First then action will throw an exception
        thenAction = std::make_unique<MockAction>();
        EXPECT_CALL(*thenAction, execute)
            .Times(1)
            .WillOnce(Throw(std::logic_error{"Communication error"}));
        thenActions.push_back(std::move(thenAction));

        // Second then action should not get executed
        thenAction = std::make_unique<MockAction>();
        EXPECT_CALL(*thenAction, execute).Times(0);
        thenActions.push_back(std::move(thenAction));

        IfAction ifAction{std::move(conditionAction), std::move(thenActions)};
        ifAction.execute(env);
        ADD_FAILURE() << "Should not have reached this line.";
    }
    catch (const std::exception& error)
    {
        EXPECT_STREQ(error.what(), "Communication error");
    }

    // Test where condition is true: then clause returns true
    try
    {
        // Create condition action that will return true
        std::unique_ptr<MockAction> conditionAction =
            std::make_unique<MockAction>();
        EXPECT_CALL(*conditionAction, execute).Times(1).WillOnce(Return(true));

        // Create vector of actions for then clause: last action returns true
        std::vector<std::unique_ptr<Action>> thenActions{};
        std::unique_ptr<MockAction> thenAction = std::make_unique<MockAction>();
        EXPECT_CALL(*thenAction, execute).Times(1).WillOnce(Return(true));
        thenActions.push_back(std::move(thenAction));

        // Create vector of actions for else clause: should not be executed
        std::vector<std::unique_ptr<Action>> elseActions{};
        std::unique_ptr<MockAction> elseAction = std::make_unique<MockAction>();
        EXPECT_CALL(*elseAction, execute).Times(0);
        elseActions.push_back(std::move(elseAction));

        IfAction ifAction{std::move(conditionAction), std::move(thenActions),
                          std::move(elseActions)};
        EXPECT_EQ(ifAction.execute(env), true);
    }
    catch (const std::exception& error)
    {
        ADD_FAILURE() << "Should not have caught exception.";
    }

    // Test where condition is true: then clause returns false
    try
    {
        // Create condition action that will return true
        std::unique_ptr<MockAction> conditionAction =
            std::make_unique<MockAction>();
        EXPECT_CALL(*conditionAction, execute).Times(1).WillOnce(Return(true));

        // Create vector of actions for then clause: last action returns false
        std::vector<std::unique_ptr<Action>> thenActions{};
        std::unique_ptr<MockAction> thenAction = std::make_unique<MockAction>();
        EXPECT_CALL(*thenAction, execute).Times(1).WillOnce(Return(false));
        thenActions.push_back(std::move(thenAction));

        // Create vector of actions for else clause: should not be executed
        std::vector<std::unique_ptr<Action>> elseActions{};
        std::unique_ptr<MockAction> elseAction = std::make_unique<MockAction>();
        EXPECT_CALL(*elseAction, execute).Times(0);
        elseActions.push_back(std::move(elseAction));

        IfAction ifAction{std::move(conditionAction), std::move(thenActions),
                          std::move(elseActions)};
        EXPECT_EQ(ifAction.execute(env), false);
    }
    catch (const std::exception& error)
    {
        ADD_FAILURE() << "Should not have caught exception.";
    }

    // Test where condition is false: else clause returns true
    try
    {
        // Create condition action that will return false
        std::unique_ptr<MockAction> conditionAction =
            std::make_unique<MockAction>();
        EXPECT_CALL(*conditionAction, execute).Times(1).WillOnce(Return(false));

        // Create vector of actions for then clause: should not be executed
        std::vector<std::unique_ptr<Action>> thenActions{};
        std::unique_ptr<MockAction> thenAction = std::make_unique<MockAction>();
        EXPECT_CALL(*thenAction, execute).Times(0);
        thenActions.push_back(std::move(thenAction));

        // Create vector of actions for else clause: last action returns true
        std::vector<std::unique_ptr<Action>> elseActions{};
        std::unique_ptr<MockAction> elseAction = std::make_unique<MockAction>();
        EXPECT_CALL(*elseAction, execute).Times(1).WillOnce(Return(true));
        elseActions.push_back(std::move(elseAction));

        IfAction ifAction{std::move(conditionAction), std::move(thenActions),
                          std::move(elseActions)};
        EXPECT_EQ(ifAction.execute(env), true);
    }
    catch (const std::exception& error)
    {
        ADD_FAILURE() << "Should not have caught exception.";
    }

    // Test where condition is false: else clause returns false
    try
    {
        // Create condition action that will return false
        std::unique_ptr<MockAction> conditionAction =
            std::make_unique<MockAction>();
        EXPECT_CALL(*conditionAction, execute).Times(1).WillOnce(Return(false));

        // Create vector of actions for then clause: should not be executed
        std::vector<std::unique_ptr<Action>> thenActions{};
        std::unique_ptr<MockAction> thenAction = std::make_unique<MockAction>();
        EXPECT_CALL(*thenAction, execute).Times(0);
        thenActions.push_back(std::move(thenAction));

        // Create vector of actions for else clause: last action returns false
        std::vector<std::unique_ptr<Action>> elseActions{};
        std::unique_ptr<MockAction> elseAction = std::make_unique<MockAction>();
        EXPECT_CALL(*elseAction, execute).Times(1).WillOnce(Return(false));
        elseActions.push_back(std::move(elseAction));

        IfAction ifAction{std::move(conditionAction), std::move(thenActions),
                          std::move(elseActions)};
        EXPECT_EQ(ifAction.execute(env), false);
    }
    catch (const std::exception& error)
    {
        ADD_FAILURE() << "Should not have caught exception.";
    }

    // Test where condition is false: no else clause specified
    try
    {
        // Create condition action that will return false
        std::unique_ptr<MockAction> conditionAction =
            std::make_unique<MockAction>();
        EXPECT_CALL(*conditionAction, execute).Times(1).WillOnce(Return(false));

        // Create vector of actions for then clause: should not be executed
        std::vector<std::unique_ptr<Action>> thenActions{};
        std::unique_ptr<MockAction> thenAction = std::make_unique<MockAction>();
        EXPECT_CALL(*thenAction, execute).Times(0);
        thenActions.push_back(std::move(thenAction));

        IfAction ifAction{std::move(conditionAction), std::move(thenActions)};
        EXPECT_EQ(ifAction.execute(env), false);
    }
    catch (const std::exception& error)
    {
        ADD_FAILURE() << "Should not have caught exception.";
    }
}

TEST(IfActionTests, GetConditionAction)
{
    MockAction* conditionAction = new MockAction{};

    std::vector<std::unique_ptr<Action>> thenActions{};

    IfAction ifAction{std::unique_ptr<Action>{conditionAction},
                      std::move(thenActions)};

    EXPECT_EQ(ifAction.getConditionAction().get(), conditionAction);
}

TEST(IfActionTests, GetThenActions)
{
    std::unique_ptr<Action> conditionAction = std::make_unique<MockAction>();

    std::vector<std::unique_ptr<Action>> thenActions{};

    MockAction* thenAction1 = new MockAction{};
    thenActions.push_back(std::unique_ptr<MockAction>{thenAction1});

    MockAction* thenAction2 = new MockAction{};
    thenActions.push_back(std::unique_ptr<MockAction>{thenAction2});

    IfAction ifAction{std::move(conditionAction), std::move(thenActions)};
    EXPECT_EQ(ifAction.getThenActions().size(), 2);
    EXPECT_EQ(ifAction.getThenActions()[0].get(), thenAction1);
    EXPECT_EQ(ifAction.getThenActions()[1].get(), thenAction2);
}

TEST(IfActionTests, GetElseActions)
{
    std::unique_ptr<Action> conditionAction = std::make_unique<MockAction>();

    std::vector<std::unique_ptr<Action>> thenActions{};

    std::vector<std::unique_ptr<Action>> elseActions{};

    MockAction* elseAction1 = new MockAction{};
    elseActions.push_back(std::unique_ptr<MockAction>{elseAction1});

    MockAction* elseAction2 = new MockAction{};
    elseActions.push_back(std::unique_ptr<MockAction>{elseAction2});

    IfAction ifAction{std::move(conditionAction), std::move(thenActions),
                      std::move(elseActions)};
    EXPECT_EQ(ifAction.getElseActions().size(), 2);
    EXPECT_EQ(ifAction.getElseActions()[0].get(), elseAction1);
    EXPECT_EQ(ifAction.getElseActions()[1].get(), elseAction2);
}

TEST(IfActionTests, ToString)
{
    // Test where else clause is not specified
    {
        std::unique_ptr<Action> conditionAction =
            std::make_unique<MockAction>();

        std::vector<std::unique_ptr<Action>> thenActions{};
        thenActions.push_back(std::make_unique<MockAction>());

        IfAction ifAction{std::move(conditionAction), std::move(thenActions)};
        EXPECT_EQ(ifAction.toString(),
                  "if: { condition: { ... }, then: [ ... ] }");
    }

    // Test where else clause is specified
    {
        std::unique_ptr<Action> conditionAction =
            std::make_unique<MockAction>();

        std::vector<std::unique_ptr<Action>> thenActions{};
        thenActions.push_back(std::make_unique<MockAction>());

        std::vector<std::unique_ptr<Action>> elseActions{};
        elseActions.push_back(std::make_unique<MockAction>());

        IfAction ifAction{std::move(conditionAction), std::move(thenActions),
                          std::move(elseActions)};
        EXPECT_EQ(ifAction.toString(),
                  "if: { condition: { ... }, then: [ ... ], else: [ ... ] }");
    }
}
