//
// © 2018-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "IoTClientDiscoveryState.h"

@interface IoTClientDiscoveryState ()

@property (nonatomic, assign) IoTClientDiscoveryInterval currentInterval;
@property (nonatomic, weak) NSTimer *activeTimer;
@property (nonatomic, weak) NSTimer *stateChangeTimer;

@end

@implementation IoTClientDiscoveryState

- (instancetype)initWithDelegate:(id<IoTClientDiscoveryStateDelegate>)delegate
{
    NSAssert([NSThread isMainThread], @"Discovery State requires run loop");
    self = [super init];
    if (self) {
        self->_currentInterval = IoTClientDiscoveryIntervalStopped;
        self->_delegate = delegate;

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidEnterBackground)
                                                     name:UIApplicationDidEnterBackgroundNotification
                                                   object:nil];

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidBecomeActive)
                                                     name:UIApplicationDidBecomeActiveNotification
                                                   object:nil];
    }
    return self;
}

- (void)dealloc
{
    [self.activeTimer invalidate];
    self.activeTimer = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)updateTimer
{
    void(^timerSetup)(void) = ^{
        NSTimeInterval interval;

        switch (self.currentInterval) {
            case IoTClientDiscoveryIntervalStopped:
                interval = -1;
                break;
            case IoTClientDiscoveryIntervalFrequent:
                interval = 1;
                break;
            case IoTClientDiscoveryIntervalRegular:
                interval = 10;
                break;

            default:
                break;
        }

        if (self.activeTimer) {
            [self.activeTimer invalidate];
            self.activeTimer = nil;
        }

        if (interval > 0) {
            NSTimer *timer = [NSTimer timerWithTimeInterval:interval
                                                     target:self
                                                   selector:@selector(timerFired:)
                                                   userInfo:nil
                                                    repeats:YES];
            [[NSRunLoop mainRunLoop] addTimer:timer
                                      forMode:NSRunLoopCommonModes];
            self.activeTimer = timer;
        }
    };

    if (![NSThread isMainThread]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            timerSetup();
        });
    } else {
        timerSetup();
    }
}

- (void)timerFired:(NSTimer *)timer
{
//    NSLog (@"Requesting Device Scan");
    [self.delegate clientDiscoverStateRequestScan];
}

- (void)start
{
    [self.stateChangeTimer invalidate];
    self.stateChangeTimer = nil;
    if (self.currentInterval == IoTClientDiscoveryIntervalStopped) {
        self.currentInterval = IoTClientDiscoveryIntervalFrequent;
        [self updateTimer];
        [self.delegate clientDiscoverStateDidStart];
    }
}

- (void)stop
{
    [self.stateChangeTimer invalidate];
    self.stateChangeTimer = nil;
    if (self.currentInterval != IoTClientDiscoveryIntervalStopped) {
        self.currentInterval = IoTClientDiscoveryIntervalStopped;
        [self updateTimer];
        [self.delegate clientDiscoverStateDidStop];
    }
}

- (void)applicationDidEnterBackground
{
    [self stop];
}

- (void)applicationDidBecomeActive
{
    [self start];
}

- (void)scanToRefindService
{
    if (self.currentInterval != IoTClientDiscoveryIntervalStopped) {
    	[self startFrequentScanAndSetUpStateChangeTimer];
    }
}

- (void)didDiscoverService
{
    if (self.currentInterval != IoTClientDiscoveryIntervalStopped) {
        [self startFrequentScanAndSetUpStateChangeTimer];
    }
}

- (void)didRemoveService:(NSInteger)remaining
{
    if (self.currentInterval == IoTClientDiscoveryIntervalStopped) {
        return;
    }
    
    if (remaining > 0) {
        [self startFrequentScanAndSetUpStateChangeTimer];
    } else {
        [self.stateChangeTimer invalidate];
        
        self.currentInterval = IoTClientDiscoveryIntervalFrequent;
        [self updateTimer];
    }
}

- (void)startFrequentScanAndSetUpStateChangeTimer
{
    if (self.currentInterval != IoTClientDiscoveryIntervalFrequent) {
        self.currentInterval = IoTClientDiscoveryIntervalFrequent;
        [self updateTimer];
    }

    [self.stateChangeTimer invalidate];
    NSTimer *timer = [NSTimer timerWithTimeInterval:5
                                             target:self
                                           selector:@selector(stateChangeTimerFired:)
                                           userInfo:nil
                                            repeats:NO];
    [[NSRunLoop mainRunLoop] addTimer:timer
                              forMode:NSRunLoopCommonModes];
    self.stateChangeTimer = timer;
}

- (void)stateChangeTimerFired:(NSTimer *)timer
{
    if (self.currentInterval == IoTClientDiscoveryIntervalFrequent) {
        self.currentInterval = IoTClientDiscoveryIntervalRegular;
        [self updateTimer];
    }
}

@end
