/*
 *    Copyright (c) 2021 Project CHIP Authors
 *    Copyright (c) 2021 SmartThings
 *    All rights reserved.
 *
 *    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 <lib/support/StateMachine.h>
#include <lib/support/UnitTestRegistration.h>
#include <nlunit-test.h>

namespace {

struct Event1
{
};
struct Event2
{
};
struct Event3
{
};
struct Event4
{
};
struct Event5
{
};

using Event   = chip::Variant<Event1, Event2, Event3, Event4, Event5>;
using Context = chip::StateMachine::Context<Event>;

struct MockState
{
    unsigned mEntered;
    unsigned mExited;
    unsigned mLogged;
    const char * mPrevious;

    void Enter() { ++mEntered; }
    void Exit() { ++mExited; }
    void LogTransition(const char * previous)
    {
        ++mLogged;
        mPrevious = previous;
    }
};

struct BaseState
{
    void Enter() { mMock.Enter(); }
    void Exit() { mMock.Exit(); }
    void LogTransition(const char * previous) { mMock.LogTransition(previous); }
    const char * GetName() { return mName; }

    chip::StateMachine::Context<Event> & mCtx;
    const char * mName;
    MockState & mMock;
};

struct State1 : public BaseState
{
    State1(Context & ctx, MockState & mock) : BaseState{ ctx, "State1", mock } {}
};

struct State2 : public BaseState
{
    State2(Context & ctx, MockState & mock) : BaseState{ ctx, "State2", mock } {}
};

struct State3 : public BaseState
{
    State3(Context & ctx, MockState & mock) : BaseState{ ctx, "State3", mock } {}
    void Enter()
    {
        BaseState::Enter();
        this->mCtx.Dispatch(Event::Create<Event5>());
    }
};

// Place State3 first in the variant.  This can evoke the behavior that
// TestNestedDispatch is looking for.
using State = chip::StateMachine::VariantState<State3, State2, State1>;

struct StateFactory
{
    Context & mCtx;
    MockState ms1{ 0, 0, 0, nullptr };
    MockState ms2{ 0, 0, 0, nullptr };
    MockState ms3{ 0, 0, 0, nullptr };

    StateFactory(Context & ctx) : mCtx(ctx) {}

    auto CreateState1() { return State::Create<State1>(mCtx, ms1); }
    auto CreateState2() { return State::Create<State2>(mCtx, ms2); }
    auto CreateState3() { return State::Create<State3>(mCtx, ms3); }
};

struct Transitions
{
    Context & mCtx;
    StateFactory mFactory;
    Transitions(Context & ctx) : mCtx(ctx), mFactory(ctx) {}

    using OptState = chip::StateMachine::Optional<State>;
    State GetInitState() { return mFactory.CreateState1(); }
    OptState operator()(const State & state, const Event & event)
    {
        if (state.Is<State1>() && event.Is<Event2>())
        {
            return mFactory.CreateState2();
        }
        if (state.Is<State2>() && event.Is<Event1>())
        {
            return mFactory.CreateState1();
        }
        if (state.Is<State1>() && event.Is<Event4>())
        {
            // legal - Dispatches event without transition
            mCtx.Dispatch(Event::Create<Event2>());
            return {};
        }
        if (state.Is<State2>() && event.Is<Event4>())
        {
            // mCtx.Dispatch(Event::Create<Event2>()); // dispatching an event and returning a transition would be illegal
            return mFactory.CreateState1();
        }
        if (state.Is<State1>() && event.Is<Event5>())
        {
            return mFactory.CreateState3();
        }
        if (state.Is<State3>() && event.Is<Event5>())
        {
            return mFactory.CreateState2();
        }

        return {};
    }
};

class SimpleStateMachine
{
public:
    Transitions mTransitions;
    chip::StateMachine::StateMachine<State, Event, Transitions> mStateMachine;

    SimpleStateMachine() : mTransitions(mStateMachine), mStateMachine(mTransitions) {}
    ~SimpleStateMachine() {}
};

void TestInit(nlTestSuite * inSuite, void * inContext)
{
    // state machine initializes to State1
    SimpleStateMachine fsm;
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State1>());
}

void TestIgnoredEvents(nlTestSuite * inSuite, void * inContext)
{
    // in State1 - ignore Event1 and Event3
    SimpleStateMachine fsm;
    fsm.mStateMachine.Dispatch(Event::Create<Event1>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State1>());
    fsm.mStateMachine.Dispatch(Event::Create<Event3>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State1>());
    // transition to State2
    fsm.mStateMachine.Dispatch(Event::Create<Event2>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
    // in State2 - ignore Event2 and Event3
    fsm.mStateMachine.Dispatch(Event::Create<Event2>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
    fsm.mStateMachine.Dispatch(Event::Create<Event3>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
}

void TestTransitions(nlTestSuite * inSuite, void * inContext)
{
    // in State1
    SimpleStateMachine fsm;
    // dispatch Event2 to transition to State2
    fsm.mStateMachine.Dispatch(Event::Create<Event2>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
    // dispatch Event1 to transition back to State1
    fsm.mStateMachine.Dispatch(Event::Create<Event1>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State1>());
    // dispatch Event2 to transition to State2
    fsm.mStateMachine.Dispatch(Event::Create<Event2>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
    // dispatch Event4 to transitions to State1.
    fsm.mStateMachine.Dispatch(Event::Create<Event4>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State1>());
}

void TestTransitionsDispatch(nlTestSuite * inSuite, void * inContext)
{
    // in State1
    SimpleStateMachine fsm;
    // Dispatch Event4, which in turn dispatches Event2 from the transitions
    // table and ultimately places us in State2.
    fsm.mStateMachine.Dispatch(Event::Create<Event4>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
}

void TestNestedDispatch(nlTestSuite * inSuite, void * inContext)
{
    // in State1
    SimpleStateMachine fsm;
    // Dispatch Event5, which places us into State3, which will dispatch
    // Event5 again from its Enter method to place us into State2.
    fsm.mStateMachine.Dispatch(Event::Create<Event5>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
    // Make sure that Enter methods execute the correct number of times.
    // This helps verify that pattern matching is working correctly.
    // Specifically, we need to verify this case: State3 creates State2
    // by dispatching Event5 from its Enter method.  This means that the
    // Dispatch call from State3 also destructs State3.  If the State3
    // Enter method pattern matching triggers Enter more than once, this
    // is use-after-destruction.  What can appear to happen is that the
    // State2 Enter method will execute twice, as State2 will already have
    // been constructed when the State3 Enter method executes a second
    // time.  The state machine pattern matching has code to explicitly
    // prevent this double-execution.  This is testing that.
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mEntered == 0);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mExited == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mLogged == 0);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mEntered == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mExited == 0);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mLogged == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms3.mEntered == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms3.mExited == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms3.mLogged == 1);
}

void TestMethodExec(nlTestSuite * inSuite, void * inContext)
{
    // in State1
    SimpleStateMachine fsm;
    // transition to State2
    fsm.mStateMachine.Dispatch(Event::Create<Event2>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State2>());
    // verify expected method calls
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mEntered == 0);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mExited == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mLogged == 0);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mPrevious == nullptr);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mEntered == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mExited == 0);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mLogged == 1);
    NL_TEST_ASSERT(inSuite, strcmp(fsm.mTransitions.mFactory.ms2.mPrevious, "State1") == 0);
    // transition back to State1
    fsm.mStateMachine.Dispatch(Event::Create<Event1>());
    NL_TEST_ASSERT(inSuite, fsm.mStateMachine.GetState().Is<State1>());
    // verify expected method calls
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mEntered == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mExited == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms1.mLogged == 1);
    NL_TEST_ASSERT(inSuite, strcmp(fsm.mTransitions.mFactory.ms1.mPrevious, "State2") == 0);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mEntered == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mExited == 1);
    NL_TEST_ASSERT(inSuite, fsm.mTransitions.mFactory.ms2.mLogged == 1);
    NL_TEST_ASSERT(inSuite, strcmp(fsm.mTransitions.mFactory.ms2.mPrevious, "State1") == 0);
}

int Setup(void * inContext)
{
    return SUCCESS;
}

int Teardown(void * inContext)
{
    return SUCCESS;
}

} // namespace

static const nlTest sTests[] = {
    NL_TEST_DEF("TestInit", TestInit),
    NL_TEST_DEF("TestIgnoredEvents", TestIgnoredEvents),
    NL_TEST_DEF("TestTransitions", TestTransitions),
    NL_TEST_DEF("TestTransitionsDispatch", TestTransitionsDispatch),
    NL_TEST_DEF("TestNestedDispatch", TestNestedDispatch),
    NL_TEST_DEF("TestMethodExec", TestMethodExec),
    NL_TEST_SENTINEL(),
};

int StateMachineTestSuite()
{
    nlTestSuite suite = { "CHIP State Machine tests", &sTests[0], Setup, Teardown };
    nlTestRunner(&suite, nullptr);
    return nlTestRunnerStats(&suite);
}

CHIP_REGISTER_TEST_SUITE(StateMachineTestSuite);
