/*
 *
 *    Copyright (c) 2014-2017 Nest Labs, Inc.
 *    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.
 */

/**
 *    @file
 *      This file implements the Weave Tunnel Connection Manager that
 *      manages the connection state machine.
 *
 */
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#ifndef _WEAVE_TUNNEL_CONNECTION_MGR_H_
#define _WEAVE_TUNNEL_CONNECTION_MGR_H_

#include <Weave/Core/WeaveCore.h>
#include <InetLayer/InetInterface.h>
#include <Weave/Profiles/WeaveProfiles.h>
#include <Weave/Profiles/ProfileCommon.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelCommon.h>
#include <Weave/Profiles/weave-tunneling/WeaveTunnelControl.h>

#if WEAVE_CONFIG_ENABLE_TUNNELING

#define SERVICE_CONN_INTF_NAME_MAX_LEN                 (16)

#define CONNECT_NO_DELAY                               (0)

namespace nl {
namespace Weave {
namespace Profiles {
namespace WeaveTunnel {

class WeaveTunnelAgent;

/**
 * The reconnect policy parameters that are used to govern the way the
 * tunnel reconnects to the Service.
 */
class ReconnectParam
{
  public:
    void PopulateReconnectParam(WEAVE_ERROR mLastConnectError = WEAVE_NO_ERROR,
                                uint32_t mStatusProfileId = kWeaveProfile_Common,
                                uint16_t mStatusCode = Common::kStatus_Success,
                                uint32_t mMinDelayToConnectSecs = 0);
    WEAVE_ERROR mLastConnectError;
    uint32_t mMinDelayToConnectSecs;
    uint32_t mStatusProfileId;
    uint16_t mStatusCode;
};

/**
 *  @class WeaveTunnelConnectionMgr
 *
 *  @brief
 *    This class encapsulates all the Weave tunnel connection states
 *    and the associated management logic and functions. An instance
 *    of this class would be used to manage the tunnel over each
 *    interface through which the Weave tunnel to the Service would
 *    exist.
 *
 */
class NL_DLL_EXPORT WeaveTunnelConnectionMgr
{
  friend class WeaveTunnelAgent;
  friend class WeaveTunnelControl;

  public:
    typedef enum TunnelConnectionState
    {
        kState_NotConnected            = 0,   /**< Used to indicate that the Weave Tunnel is not connected */
        kState_Connecting              = 1,   /**< Used to indicate that the Weave Tunnel connection has been initiated */
        kState_ConnectionEstablished   = 2,   /**< Used to indicate that the Weave Tunnel connection is established and route information is being exchanged */
        kState_TunnelOpen              = 3,   /**< Used to indicate that the Weave Tunnel is open and ready for data traffic transit */
        kState_TunnelClosing           = 4,   /**< Used to indicate that the Weave Tunnel is closing and the connection is being torn down */
        kState_ReconnectRecvd          = 5,   /**< Used to indicate that the Service wants the border gateway to reconnect after a directory lookup */
    } TunnelConnectionState;

    typedef enum TunnelConnNotifyReasons
    {
        kStatus_TunDown                    = 0,   /**< Used to indicate that the Weave tunnel has gone down */
        kStatus_TunPrimaryUp               = 1,   /**< Used to indicate that the primary Weave tunnel is up */
        kStatus_TunPrimaryConnError        = 2,   /**< Used to indicate that a primary tunnel connection attempt has failed or an existing one was locally aborted or closed by peer */
        kStatus_TunBackupConnError         = 3,   /**< Used to indicate that a backup tunnel connection attempt has failed or an existing one was locally aborted or closed by peer */
        kStatus_TunFailoverToBackup        = 4,   /**< Used to indicate that the primary tunnel is down and switchover to backup tunnel has occurred */
        kStatus_TunBackupOnlyDown          = 5,   /**< Used to indicate that the backup tunnel is down */
        kStatus_TunBackupUp                = 6,   /**< Used to indicate that the Backup Weave tunnel is up */
        kStatus_TunPrimaryAndBackupUp      = 7,   /**< Used to indicate that both the Primary and Backup Weave tunnel are up */
        kStatus_TunPrimaryReconnectRcvd    = 8,   /**< Used to indicate that the Service has requested a reconnect for the Primary Weave tunnel */
        kStatus_TunBackupReconnectRcvd     = 9,   /**< Used to indicate that the Service has requested a reconnect for the Backup Weave tunnel */
        kStatus_TunPrimaryLiveness         = 10,  /**< Used to indicate information about the Tunnel Liveness probe on the Primary Weave tunnel */
        kStatus_TunBackupLiveness          = 11,  /**< Used to indicate information about the Tunnel Liveness probe on the Backup Weave tunnel */

    } TunnelConnNotifyReasons;

    WeaveTunnelConnectionMgr(void);

#if WEAVE_CONFIG_PERSIST_CONNECTED_SESSION
/**
 * Check if a persisted secure session for the tunnel exists
 */
    typedef bool (*PersistedSecureSessionExistsFunct)(uint64_t peerNodeId);
    PersistedSecureSessionExistsFunct IsPersistedTunnelSessionPresent;

/**
 * Populate the persisted secure session within the passed WeaveConnection object
 */
    typedef void (*LoadPersistedSessionFunct)(WeaveConnection *con);
    LoadPersistedSessionFunct LoadPersistedTunnelSession;

    void SetCallbacksForPersistedTunnelConnection(PersistedSecureSessionExistsFunct aIsPersistedTunnelSessionPresent,
                                                  LoadPersistedSessionFunct aLoadPersistedTunnelSession);

#endif // WEAVE_CONFIG_PERSIST_CONNECTED_SESSION

/**
 * Initialize the WeaveTunnelConnectionMgr.
 */
    WEAVE_ERROR Init(WeaveTunnelAgent *tunAgent, TunnelType tunType, SrcInterfaceType srcIntfType,
                     const char *connIntfName = NULL);

/**
 * Shutdown the WeaveTunnelConnectionMgr.
 *
 */
    void Shutdown(void);

#if WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
/**
 * Configure the TCP user timeout.
 */
    WEAVE_ERROR ConfigureConnTimeout(uint16_t maxTimeoutSecs);
#endif // WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
/**
 * Configure the TCP keepalive parameters.
 */
    WEAVE_ERROR ConfigureAndEnableTCPKeepAlive(uint16_t intervalSecs, uint16_t maxNumProbes);
#endif // WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
/**
 * Configure the Tunnel Liveness interval.
 */
    void ConfigureTunnelLivenessInterval(uint16_t livenessIntervalSecs);
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

/**
 * Set InterfaceName for Tunnel connection.
 */
    void SetInterfaceName(const char *intfName);

/**
 * Set SrcInterfaceType for Tunnel connection.
 */
    void SetInterfaceType(const SrcInterfaceType srcIntfType);

/**
 * Handler invoked if the Service Manager failed to establish the TCP connection to the Service.
 */
    static void ServiceMgrStatusHandler(void* appState, WEAVE_ERROR err, StatusReport *report);

/**
 * Handler invoked when Service TCP connection is completed. The device proceeds to initiate Tunnel control
 * commands to the Service from this function.
 */
    static void HandleServiceConnectionComplete(WeaveConnection *con, WEAVE_ERROR conErr);

#if WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK
/**
 * Handler invoked when the Idle state of the underlying TCP connection's send channel changes.
 */
    static void HandleTCPSendIdleChanged(TCPEndPoint *tcpEndPoint, bool isIdle);
#endif // WEAVE_CONFIG_TUNNEL_ENABLE_TCP_IDLE_CALLBACK

/**
 * Handler invoked when Service TCP connection is closed. The device tries to re-establish the connection to
 * the Service if the mServiceConKeepAlive is set to true.
 */
    static void HandleServiceConnectionClosed(WeaveConnection *con, WEAVE_ERROR conErr);

/**
 * Handler to receive tunneled IPv6 packets from the Service TCP connection and forward to the Tunnel
 * EndPoint interface after decapsulating the raw IPv6 packet from inside the tunnel header.
 */
    static void RecvdFromService(WeaveConnection *con, const WeaveMessageInfo *msgInfo,
                                 PacketBuffer *message);

/**
 * @brief Callback to fetch the interval of time to wait before the next
 * tunnel reconnect.
 *
 * @param[in] appState          App state pointer set during initialization of
 *                              the SubscriptionClient.
 * @param[in] reconnectParam    Structure with parameters that influence the calculation of the
 *                              reconnection delay.
 *
 * @param[out] delayMsec        Time in milliseconds to wait before next
 *                              reconnect attempt.
 */
    typedef void (*ConnectPolicyCallback) (void * const appState,
                                           ReconnectParam & reconnectParam,
                                           uint32_t & delayMsec);

    ConnectPolicyCallback mServiceConnDelayPolicyCallback;

    static void DefaultReconnectPolicyCallback(void * const appstate,
                                               ReconnectParam & reconnectParam,
                                               uint32_t & delayMsec);

/**
 * Attempt to establish a connection to the Service.
 */
    WEAVE_ERROR TryConnectingNow(void);

/**
 * Close the Service tunnel.
 */
    void ServiceTunnelClose(WEAVE_ERROR err);

/**
 * Stop Service tunnel connection and attempt to reconnect again.
 */
    void StopAndReconnectTunnelConn(ReconnectParam & reconnParam);


#if WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
    void SetConnectionRepairInfoCallback(nl::Weave::WeaveConnection::ConnectionRepairInfoGetterFunct aGetConnectionRepairInfo, void *repairCtxt);
#endif // WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED

/**
 * Get a pointer to the Weave Tunnel Connection object for this
 * Tunnel Connection Manager.
 */
    nl::Weave::WeaveConnection * GetTunnelConnection(void) const;
  private:

    WEAVE_ERROR StartServiceTunnelConn(uint64_t destNodeId, IPAddress destIPAddr,
                                       uint16_t destPort,
                                       WeaveAuthMode authMode,
                                       InterfaceId connIntfId);
    void StopServiceTunnelConn(WEAVE_ERROR err);
    void AttemptReconnect(ReconnectParam &reconnParam);
    void DecideOnReconnect(ReconnectParam &reconnParam);
    void ResetCacheAndScheduleConnect(uint32_t delay);
    void ScheduleConnect(uint32_t delay);
    void CancelDelayedReconnect(void);
    void ReleaseResourcesAndStopTunnelConn(WEAVE_ERROR err);
    WEAVE_ERROR ResetReconnectBackoff(bool reconnectImmediately);
    static void ServiceConnectTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
    WEAVE_ERROR AllocateAndPrepTunnelConnection(WeaveConnection **con);
#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
    void StartLivenessTimer(void);
    void StopLivenessTimer(void);
    void RestartLivenessTimer(void);
    static void TunnelLivenessTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

    void SetOnlineCheckIntervalFast(bool aProbeFast);
    void StartOnlineCheck(void);
    void StopOnlineCheck(void);
    void ReStartOnlineCheck(void);
    static void OnlineCheckTimeout(System::Layer* aSystemLayer, void* aAppState, System::Error aError);
    void HandleOnlineCheckResult(bool isOnline);
#if WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
    WEAVE_ERROR AttemptRepairTunnelConnection(uint64_t peerNodeId, WeaveAuthMode aAuthMode,
                                              nl::Inet::InterfaceId aConnIntfId = INET_NULL_INTERFACEID);
#endif // WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED

    // Pointer to a Weave Tunnel Agent object.

    WeaveTunnelAgent *mTunAgent;

    // Tunnel control object

    WeaveTunnelControl mTunControl;

    // State of the Weave Tunnel Connection

    TunnelConnectionState mConnectionState;

    // Number of failed Service Tunnel connection attempts in a row

    uint16_t mTunFailedConnAttemptsInRow;

    // Maximum number of failed Service connection attempts before notification

    uint16_t mMaxFailedConAttemptsBeforeNotify;

    // The fibonacci index of the reconnect backoff.

    uint16_t mTunReconnectFibonacciIndex;
    // The tunnel type of this connection

    TunnelType mTunType;

    // Flag to indicate that the ResetReconnect timer is armed

    bool mResetReconnectArmed;

    // The interface type for this connection

    SrcInterfaceType mSrcInterfaceType;

    // The interface identifier for the tunnel connection to the Service

    char mServiceConIntf[SERVICE_CONN_INTF_NAME_MAX_LEN];

    // Handle to the Weave connection object.

    WeaveConnection *mServiceCon;

#if WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED
    // TCP connection keepalive interval (in secs)

    uint16_t mKeepAliveIntervalSecs;

    // The max number of TCP KeepAlive probes

    uint16_t mMaxNumProbes;
#endif // WEAVE_CONFIG_TUNNEL_TCP_KEEPALIVE_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED
    // Tunnel TCP connection max user timeout (in secs)

    uint16_t mMaxUserTimeoutSecs;

#endif // WEAVE_CONFIG_TUNNEL_TCP_USER_TIMEOUT_SUPPORTED

#if WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED
    // Tunnel Liveness interval

    uint16_t mTunnelLivenessInterval;
#endif // WEAVE_CONFIG_TUNNEL_LIVENESS_SUPPORTED

    // Flag to check if the network is online for this Tunnel.

    bool mIsNetworkOnline;

    // The current periodic interval for performing any online checks
    // over the network.

    uint16_t mOnlineCheckInterval;
#if WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
    nl::Weave::WeaveConnection::ConnectionRepairInfoGetterFunct mConnRepairInfoGet;
    void *mConnRepairCtxt; // A pointer to an application-specific context object used for repair info retrieval.
#endif // WEAVE_CONFIG_TCP_CONN_REPAIR_SUPPORTED
};

} // namespace WeaveTunnel
} // namespace Profiles
} // namespace Weave
} // namespace nl

#endif // WEAVE_CONFIG_ENABLE_TUNNELING
#endif//_WEAVE_TUNNEL_CONNECTION_MGR_H_
