/*
 *
 *    Copyright (c) 2021 Project CHIP Authors
 *
 *    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.
 */

/**
 *    @file
 *      This file defines the internal classes used by CHIP Channel.
 */

#pragma once

#include <variant>

#include <channel/Channel.h>
#include <lib/core/ReferenceCounted.h>
#include <lib/dnssd/platform/Dnssd.h>
#include <lib/support/Variant.h>
#include <protocols/secure_channel/CASESession.h>
#include <transport/SecureSession.h>
#include <transport/SessionManager.h>

namespace chip {
namespace Messaging {

class ExchangeManager;
class ChannelContext;
class ChannelManager;

class ChannelContextDeletor
{
public:
    static void Release(ChannelContext * context);
};

/**
 * @brief
 *  The object of the class holds all state of a channel. It is a state machine, with following states:
 *
 *  N: None, the initial state
 *  P: Preparing
 *  R: Ready, the channel is ready to use
 *  C: Closed, the channel is closed
 *  F: Failed, the channel is failed
 *
 *    +---+   +---+   +---+   +---+
 *    | N |-->| P |-->| R |-->| C |
 *    +---+   +---+   +---+   +---+
 *              |       |
 *              |       |     +---+
 *              +-------+---->| F |
 *                            +---+
 *
 *  Note: The state never goes back, when a channel is failed, it can't be reset or fixed. The application must create a
 *  new channel to replace the failed channel
 *
 *  Preparing Substates:
 *    A: AddressResolving, use mDNS to resolve the node address
 *    C: CasePairing, do SIGMA key exchange
 *    CD: CasePairingDone, wait for OnNewConnection from SecureSessionManager
 *
 *  /---\   +---+   +---+   +----+   /---\
 *  |   |-->| A |-->| C |-->| CD |-->| O |
 *  \---/   +---+   +---+   +----+   \---/
 */
class ChannelContext : public ReferenceCounted<ChannelContext, ChannelContextDeletor>, public SessionEstablishmentDelegate
{
public:
    ChannelContext(ExchangeManager * exchangeManager, ChannelManager * channelManager) :
        mState(ChannelState::kNone), mExchangeManager(exchangeManager), mChannelManager(channelManager), mFabricsTable(nullptr),
        mFabricIndex(kUndefinedFabricIndex)
    {}

    void Start(const ChannelBuilder & builder);

    /*
     * @brief
     *  Create a new exchange on the channel.
     *
     * @pre GetState() == ChannelState::kReady
     */
    ExchangeContext * NewExchange(ExchangeDelegate * delegate);

    ChannelState GetState() const { return mState; }

    bool MatchNodeId(NodeId nodeId);
    bool MatchTransport(Transport::Type transport);
    bool MatchTransportPreference(ChannelBuilder::TransportPreference transport);
    bool MatchCaseParameters();

    bool IsCasePairing();

    bool MatchesBuilder(const ChannelBuilder & builder);
    bool MatchesSession(SessionHandle session, SessionManager * sessionManager);

    // events of ResolveDelegate, propagated from ExchangeManager
    void HandleNodeIdResolve(CHIP_ERROR error, uint64_t nodeId, const Dnssd::DnssdService & address);

    // events of SecureSessionManager, propagated from ExchangeManager
    void OnNewConnection(SessionHandle session);
    void OnConnectionExpired(SessionHandle session);

    // Pairing callbacks
    void OnSessionEstablishmentError(CHIP_ERROR error) override;
    void OnSessionEstablished() override;

private:
    friend class ChannelContextDeletor;
    friend class ChannelHandle;

    ChannelState mState;
    ExchangeManager * mExchangeManager;
    ChannelManager * mChannelManager;
    FabricTable * mFabricsTable;
    FabricIndex mFabricIndex;

    enum class PrepareState
    {
        kAddressResolving,
        kCasePairing,
        kCasePairingDone,
    };

    // mPreparing is pretty big, consider move it outside
    struct PrepareVars
    {
        PrepareState mState;
        Inet::IPAddressType mAddressType;
        Inet::IPAddress mAddress;
        CASESession * mCasePairingSession;
        ChannelBuilder mBuilder;
    };

    struct ReadyVars
    {
        ReadyVars(SessionHandle session) : mSession(session) {}
        const SessionHandle mSession;
    };

    Variant<PrepareVars, ReadyVars> mStateVars;

    PrepareVars & GetPrepareVars() { return mStateVars.Get<PrepareVars>(); }
    ReadyVars & GetReadyVars() { return mStateVars.Get<ReadyVars>(); }

    // State machine functions
    void EnterPreparingState(const ChannelBuilder & builder);
    void ExitPreparingState();

    void EnterReadyState(SessionHandle session);
    void ExitReadyState();

    void EnterFailedState(CHIP_ERROR error);
    void EnterClosedState();

    // Preparing sub-states
    void EnterAddressResolve();
    static void AddressResolveTimeout(System::Layer * aLayer, void * aAppState);
    void AddressResolveTimeout();
    void ExitAddressResolve() {}

    void EnterCasePairingState();
    void ExitCasePairingState();
};

class ChannelContextHandleAssociation
{
public:
    ChannelContextHandleAssociation(ChannelContext * channelContext, ChannelDelegate * channelDelegate) :
        mChannelContext(channelContext), mChannelDelegate(channelDelegate)
    {
        mChannelContext->Retain();
    }
    ~ChannelContextHandleAssociation() { mChannelContext->Release(); }

private:
    friend class ChannelManager;
    friend class ChannelHandle;
    ChannelContext * mChannelContext;
    ChannelDelegate * mChannelDelegate;
};

} // namespace Messaging
} // namespace chip
