/*
 *
 *    Copyright (c) 2015-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 NLWeaveStack interface
 *
 */

#import <Foundation/Foundation.h>

#import "NLWeaveStack.h"
#import "NLLogging.h"

#include <Weave/Core/WeaveCore.h>
#include <Weave/Core/WeaveError.h>
#include <Weave/Support/CodeUtils.h>
#import "NLWeaveBleDelegate_Protected.h"
#import "NLWeaveDeviceManager.h"
#import "NLWeaveDeviceManager_Protected.h"

@interface NLWeaveStack ()
{
    dispatch_queue_t                _mWorkQueue;
    dispatch_queue_t                _mSelectQueue;
    nl::Weave::System::Layer        _mSystemLayer;
    nl::Inet::InetLayer             _mInetLayer;
    nl::Weave::WeaveFabricState     _mFabricState;
    nl::Weave::WeaveMessageLayer    _mMessageLayer;
    nl::Weave::WeaveExchangeManager _mExchangeMgr;
    nl::Weave::WeaveSecurityManager _mSecurityMgr;

    // for shutdown
    bool                            _mIsWaitingOnSelect;
    ShutdownCompletionBlock         _mShutdownCompletionBlock;

#if CONFIG_NETWORK_LAYER_BLE
    nl::Ble::BleLayer               _mBleLayer;
    NLWeaveBleDelegate *            _mBleDelegate;
#endif // #if CONFIG_NETWORK_LAYER_BLE
    /*
    int selectRes;
    int MaxNumberedFdPlusOne;
    struct timeval sleepTime;
    fd_set readFDs, writeFDs, exceptFDs;
     */
}

-(WEAVE_ERROR)InitStack_internal:(NSString *) listenAddr bleDelegate:(NLWeaveBleDelegate *)bleDelegate;
-(void)ShutdownStack_Stage1;
-(void)ShutdownStack_Stage2;
-(void)TryProcessNetworkEvents;

- (instancetype)init NS_DESIGNATED_INITIALIZER;

@end

@implementation NLWeaveStack

@synthesize WorkQueue = _mWorkQueue;

@synthesize BleDelegate = _mBleDelegate;

#if CONFIG_NETWORK_LAYER_BLE
#endif //#if CONFIG_NETWORK_LAYER_BLE

/**
    @note
      This function can only be called by the ARC runtime
 */
- (void)dealloc
{
    // This method can only be called by ARC
    // Let's not rely on this unpredictable mechanism for de-initialization
    // application shall call ShutdownStack if it want to cleanly destroy everything before application termination
    WDM_LOG_METHOD_SIG();
}

/**
    @note
      This function can be called from any thread/queue at any time
 */
+ (instancetype)sharedStack
{
    static NLWeaveStack *mStack = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        mStack = [[self alloc] init];
    });

    return mStack;
}

/**
    @note
      This function can only be called indirectly via sharedStack
 */
- (instancetype)init
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    WDM_LOG_METHOD_SIG();

    self = [super init];
    VerifyOrExit((self), err = WEAVE_ERROR_NO_MEMORY);

    _currentState = kWeaveStack_NotInitialized;

    // create a serial work queue for all direct Weave operations
    _mWorkQueue = dispatch_queue_create("com.nestlabs.queue.weave.work", DISPATCH_QUEUE_SERIAL);
    VerifyOrExit((_mWorkQueue), err = WEAVE_ERROR_NO_MEMORY);

    // create a serial work queue for all the select loop to wait on
    _mSelectQueue = dispatch_queue_create("com.nestlabs.queue.weave.select", DISPATCH_QUEUE_SERIAL);
    VerifyOrExit((_mSelectQueue), err = WEAVE_ERROR_NO_MEMORY);

    _mIsWaitingOnSelect  = false;

    _currentState = kWeaveStack_QueueInitialized;

exit:
    id result = nil;
    if (WEAVE_NO_ERROR == err)
    {
        result = self;
    }
    else
    {
        if (self)
        {
            if (_mWorkQueue)
            {
                _mWorkQueue = nil;
            }

            if (_mSelectQueue)
            {
                _mSelectQueue = nil;
            }
        }

        // ErrorStr uses more than one global resources which cannot be safely accessed
        // from other threads without locking, so we just log the number here
        WDM_LOG_ERROR(@"Error in init : %d\n", err);
    }
    return result;
}

/**
    @note
      This function can only be called indirectly via InitStack, within the Weave workqueue.
 */
-(WEAVE_ERROR)InitStack_internal:(NSString *) listenAddr bleDelegate:(NLWeaveBleDelegate *)bleDelegate
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    nl::Weave::WeaveMessageLayer::InitContext initContext;

    VerifyOrExit((kWeaveStack_QueueInitialized == self.currentState), err = WEAVE_ERROR_INCORRECT_STATE);

    self.currentState = kWeaveStack_Initializing;

    _mIsWaitingOnSelect  = false;

    // Initialize the System::Layer object
    err = _mSystemLayer.Init(NULL);
    SuccessOrExit(err);

    // Initialize the InetLayer object.
    err = _mInetLayer.Init(_mSystemLayer, NULL);
    SuccessOrExit(err);

    // Initialize the FabricState object.
    err = _mFabricState.Init();
    SuccessOrExit(err);

    // TODO: TEMPORARY HACK -- use a different default node id to avoid conflict with the mock device.
    _mFabricState.LocalNodeId = 2;

    // Configure the weave listening address, if one was provided
    {
        if (listenAddr != NULL)
        {
#if WEAVE_CONFIG_ENABLE_TARGETED_LISTEN
            const char *listenAddrStr = ([listenAddr length] != 0) ? [listenAddr UTF8String] : NULL;

            nl::Inet::IPAddress addr;
            if (nl::Inet::IPAddress::FromString(listenAddrStr, addr))
            {
                _mFabricState.ListenIPv4Addr = addr;
            }
#else
            WDM_LOG_ERROR(@"Error in InitStack: targeted listening is not enabled");
            ExitNow(err = WEAVE_ERROR_INVALID_ARGUMENT);
#endif
        }
    }

#if CONFIG_NETWORK_LAYER_BLE
    if (nil != bleDelegate)
    {
        // retain the BLE Delegate provided by the application layer
        _mBleDelegate = bleDelegate;
        initContext.listenBLE = true;
    }
    else
    {
        _mBleDelegate = [[NLWeaveBleDelegate alloc] initDummyDelegate];
        initContext.listenBLE = false;
    }

    // Initialize the BleLayer
    err = _mBleLayer.Init([_mBleDelegate GetPlatformDelegate], [_mBleDelegate GetApplicationDelegate], &_mSystemLayer);
    SuccessOrExit(err);

    [_mBleDelegate SetBleLayer:&_mBleLayer];

    initContext.ble = &_mBleLayer;
#endif

    // Initialize the WeaveMessageLayer object.
    initContext.systemLayer = &_mSystemLayer;
    initContext.inet = &_mInetLayer;
    initContext.fabricState = &_mFabricState;
    initContext.listenTCP = false;
    initContext.listenUDP = true;
    err = _mMessageLayer.Init(&initContext);
    SuccessOrExit(err);

    // Initialize the Exchange Manager object.
    err = _mExchangeMgr.Init(&_mMessageLayer);
    SuccessOrExit(err);

    // Initialize the Security Manager object.
    err = _mSecurityMgr.Init(_mExchangeMgr, _mSystemLayer);
    SuccessOrExit(err);

    self.currentState = kWeaveStack_FullyInitialized;

    [self TryProcessNetworkEvents];

exit:
    if (WEAVE_NO_ERROR != err)
    {
        WDM_LOG_ERROR(@"Error in InitStack_internal : (%d) %@\n", err, [NSString stringWithUTF8String:nl::ErrorStr(err)]);
    }

    return err;
}

/**
    @note
      This function can be called from any thread/queue at any time
 */
-(WEAVE_ERROR)InitStack:(NSString *) listenAddr bleDelegate:(NLWeaveBleDelegate *)bleDelegate
{
    // initialize the stack
    WDM_LOG_METHOD_SIG();

    __block WEAVE_ERROR result = WEAVE_NO_ERROR;

    dispatch_sync(_mWorkQueue, ^(void)
    {
        result = [self InitStack_internal:listenAddr bleDelegate:bleDelegate];
    });

    if (WEAVE_NO_ERROR != result)
    {
        // ErrorStr uses more than one global resources which cannot be safely accessed
        // from other threads without locking, so we just log the number here
        WDM_LOG_ERROR(@"Error in InitStack : %d\n", result);
    }

    return result;
}

/**
    @note
      This function can only be called indirectly via TryProcessNetworkEvents, within the Weave workqueue.
 */
-(void)ShutdownStack_Stage2
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    ShutdownCompletionBlock block = _mShutdownCompletionBlock;

    WDM_LOG_METHOD_SIG();

    _mShutdownCompletionBlock = nil;

    WDM_LOG_DEBUG(@"Shutdown Security Manager\n");
    _mSecurityMgr.Shutdown();

    WDM_LOG_DEBUG(@"Shutdown Exchange Manager\n");
    _mExchangeMgr.Shutdown();

    WDM_LOG_DEBUG(@"Shutdown Message Layer\n");
    _mMessageLayer.Shutdown();

#if CONFIG_NETWORK_LAYER_BLE
    WDM_LOG_DEBUG(@"Shutdown BLE Layer\n");
    _mBleLayer.Shutdown();
#endif

    WDM_LOG_DEBUG(@"Shutdown Fabric State\n");
    _mFabricState.Shutdown();

    WDM_LOG_DEBUG(@"Shutdown Inet Layer\n");
    _mInetLayer.Shutdown();

    WDM_LOG_DEBUG(@"Shutdown Weave System Layer\n");
    _mSystemLayer.Shutdown();

    WDM_LOG_DEBUG(@"Shutdown completed\n");

    self.currentState = kWeaveStack_QueueInitialized;

    if (WEAVE_NO_ERROR != err)
    {
        WDM_LOG_ERROR(@"Error in ShutdownStack_Stage2 : (%d) %@\n", err, [NSString stringWithUTF8String:nl::ErrorStr(err)]);
    }

    // inform application layer about the completion, if so desired
    if (block)
    {
        block(err);
    }
}

/**
    @note
      This function can only be called indirectly via ShutdownStack, within the Weave workqueue.
 */
-(void)ShutdownStack_Stage1
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    WDM_LOG_METHOD_SIG();

    switch (self.currentState)
    {
        case kWeaveStack_Initializing:
        case kWeaveStack_FullyInitialized:
            // continue shutting down
            break;
        case kWeaveStack_QueueInitialized:
            // do nothing and just return without error
            ExitNow();
        default:
            // abort shutting down
            ExitNow(err = WEAVE_ERROR_INCORRECT_STATE);
    }

    self.currentState = kWeaveStack_ShuttingDown;

    if (_mIsWaitingOnSelect)
    {
        // Inform the select queue that it's time to leave
        _mSystemLayer.WakeSelect();
    }
    else
    {
        // invoke stage 2 directly, as the select queue is not active (probably the initialization failed)
        [self ShutdownStack_Stage2];
    }

exit:
    if (WEAVE_NO_ERROR != err)
    {
        WDM_LOG_ERROR(@"Error in ShutdownStack_Stage1 : (%d) %@\n", err, [NSString stringWithUTF8String:nl::ErrorStr(err)]);

        _mShutdownCompletionBlock(err);
    }
}

/**
    @note
      This function can be called from any thread/queue at any time
 */
- (void)ShutdownStack:(ShutdownCompletionBlock)block;
{
    WEAVE_ERROR result = WEAVE_NO_ERROR;

    // release all C/C++ resources at here, if possible
    WDM_LOG_METHOD_SIG();

    // We're dispatching using sync on a serial queue, so it's safe to assume
    // everything dispatched earlier has been finished
    dispatch_sync(_mWorkQueue, ^(void)
    {
        _mShutdownCompletionBlock = block;
        [self ShutdownStack_Stage1];
    });

    if (WEAVE_NO_ERROR != result)
    {
        // ErrorStr uses more than one global resources which cannot be safely accessed
        // from other threads without locking, so we just log the number here
        WDM_LOG_ERROR(@"Error in ShutdownStack : %d\n", result);
    }
}

/**
    @note
      This function can only be called indirectly via initStack, within the Weave workqueue.
 */
-(void)TryProcessNetworkEvents
{
    __block struct timeval sleepTime;
    __block fd_set readFDs, writeFDs, exceptFDs;
    int MaxNumberedFdPlusOne = 0;
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    //WDM_LOG_METHOD_SIG();

    VerifyOrExit(kWeaveStack_FullyInitialized == self.currentState, err = WEAVE_ERROR_INCORRECT_STATE);

    FD_ZERO(&readFDs);
    FD_ZERO(&writeFDs);
    FD_ZERO(&exceptFDs);

    sleepTime.tv_sec = 10;
    sleepTime.tv_usec = 0;

    // Collect the currently active file descriptors.
    _mSystemLayer.PrepareSelect(MaxNumberedFdPlusOne, &readFDs, &writeFDs, &exceptFDs, sleepTime);
    _mInetLayer.PrepareSelect(MaxNumberedFdPlusOne, &readFDs, &writeFDs, &exceptFDs, sleepTime);

    //WDM_LOG_DEBUG(@"Sleeping for %f sec.\n", sleepTime.tv_sec + (sleepTime.tv_usec / 1000000.0));

    _mIsWaitingOnSelect = true;

    // need this bracket to use the VerifyOrExit macro
    {
    dispatch_async(_mSelectQueue, ^(void)
    {
        // Wait for for I/O or for the next timer to expire.
        // Note that this is not a good practice to use with GCD, but it's
        int selectRes = select(MaxNumberedFdPlusOne, &readFDs, &writeFDs, &exceptFDs, &sleepTime);

        dispatch_async(_mWorkQueue, ^(void)
        {
            _mIsWaitingOnSelect = false;

            if (kWeaveStack_ShuttingDown == self.currentState)
            {
                WDM_LOG_DEBUG(@"Select queue woke up but we're shutting down\n");

                // continue on the 2nd stage of shutting down
                [self ShutdownStack_Stage2];
            }
            else if (kWeaveStack_FullyInitialized == self.currentState)
            {
                // Perform I/O and/or dispatch timers.
                _mSystemLayer.HandleSelectResult(selectRes, &readFDs, &writeFDs, &exceptFDs);
                _mInetLayer.HandleSelectResult(selectRes, &readFDs, &writeFDs, &exceptFDs);

                // It's wierd that with iOS 9 SDK, we have to use disaptch_after here,
                // instead of directly calling TryProcessNetworkEvents nor dispatch_async.
                // If not, the memory usage skyrockets like there is memory leak
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_MSEC), _mWorkQueue, ^(void)
                               {
                                   [self TryProcessNetworkEvents];
                               });
            }
            else
            {
                WDM_LOG_ERROR(@"Select queue woke up in unexpected state\n");
            }
        });
    });
    }

exit:
    if (WEAVE_NO_ERROR != err)
    {
        // ErrorStr uses more than one global resources which cannot be safely accessed
        // from other threads without locking, so we just log the number here
        WDM_LOG_ERROR(@"Error in TryProcessNetworkEvents : %d\n", err);
    }
}

-(NLWeaveDeviceManager *)createDeviceManager:(NSString *)name appCallbackQueue:(dispatch_queue_t)appCallbackQueue
{
    WDM_LOG_METHOD_SIG();

    NLWeaveDeviceManager *wdm = [[NLWeaveDeviceManager alloc] init:name weaveWorkQueue:_mWorkQueue appCallbackQueue:appCallbackQueue exchangeMgr:&_mExchangeMgr securityMgr:&_mSecurityMgr];
    if (nil == wdm)
    {
        WDM_LOG_ERROR(@"Cannot create new NLWeaveDeviceManager\n");
    }
    return wdm;
}

@end
