//
//  NetworkServiceHandler.m
//  SmartCity
//
//  Created by Jason Lee on 2/15/16.
//  Copyright © 2016 ntels. All rights reserved.
//
#import "JDObject.h"
#import "NetworkServiceHandler.h"
#import "Reachability.h"


@interface NetworkServiceHandler () <NSNetServiceBrowserDelegate, NSNetServiceDelegate> {
    NSNetServiceBrowser *_netServiceBrowser;
    BOOL _isNotFirstLoading;
    Reachability *_reachability;
}

@property (strong, nonatomic)  NSNetService *netService;

@end

@implementation NetworkServiceHandler


- (BOOL)startSearchBonjourServices {
    NSLog(@"%s\n currentReachabilityStatus= %zd", __PRETTY_FUNCTION__, _reachability.currentReachabilityStatus);
    
//    _isNotFirstLoading = NO;
    if (_reachability.currentReachabilityStatus != ReachableViaWiFi) {
        return NO;
    }
    
    //1.check if wifi
//    if (_netServiceBrowser) {
//        [_netServiceBrowser stop];
//        _netServiceBrowser = nil;
//    }
    
    NSString *browseType;
    if (!_netService) {
        _netServiceBrowser = [[NSNetServiceBrowser alloc] init];
        _netServiceBrowser.delegate = self;
        
        browseType = @"_services._dns-sd._udp.";
        [_netServiceBrowser searchForServicesOfType:browseType inDomain:@""];
    } else {
        [self publishNetService];
//        NSString *fullDomainName = [NSString stringWithFormat:@"%@.%@", _netService.name, _netService.type];
//        NSArray *domainNameParts = [fullDomainName componentsSeparatedByString:@"."];
//        NSLog(@"%s\n %@, %@", __PRETTY_FUNCTION__, [domainNameParts objectAtIndex:0], [domainNameParts objectAtIndex:1]);
//
//        browseType = [NSString stringWithFormat:@"%@.%@.", [domainNameParts objectAtIndex:0], [domainNameParts objectAtIndex:1]];
//        browseType = _netService.type;
    }
    
    return YES;
}

- (void)publishNetService {
    NSLog(@"%s\n %@", __PRETTY_FUNCTION__, [JDFacade facade].deviceHostName);
    
    if (!_netService) {
        _netService = [[NSNetService alloc] initWithDomain:@"" type:@"_ntels._tcp" name:[JDFacade facade].deviceHostName port:7979];
        _netService.delegate = self;
    }
    
    if (_netService) {
        [_netService publish];
        
    } else {
        NSLog(@"An error occurred initializing the NSNetService object.");
    }
}


#pragma mark - NSNetServiceDelegate methods

- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didFindService:(NSNetService *)service moreComing:(BOOL)moreComing {

    if (!_isNotFirstLoading) {    
        [self publishNetService];
        _isNotFirstLoading = YES;
    }
}

- (void)netServiceDidPublish:(NSNetService *)sender {
    NSLog(@"%s\n %@", __PRETTY_FUNCTION__, sender);
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(didSucceedPublishService)]) {
        [self.delegate didSucceedPublishService];
    }
}

- (void)netServiceWillPublish:(NSNetService *)sender {
    NSLog(@"%s\n %@", __PRETTY_FUNCTION__, sender);
    
}

- (void)netServiceDidStop:(NSNetService *)sender {
    NSLog(@"%s\n %@", __PRETTY_FUNCTION__, sender);
    
}

- (void)netService:(NSNetService *)sender didAcceptConnectionWithInputStream:(NSInputStream *)inputStream outputStream:(NSOutputStream *)outputStream {
    NSLog(@"%s\n %@", __PRETTY_FUNCTION__, sender);
    
}

- (void)netService:(NSNetService *)sender didNotPublish:(NSDictionary<NSString *,NSNumber *> *)errorDict {
    NSLog(@"%s\n %@", __PRETTY_FUNCTION__, errorDict);
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(didFailPublishService:)]) {
        [self.delegate didFailPublishService:errorDict];
    }
}

- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict {
    NSLog(@"%s\n %@", __PRETTY_FUNCTION__, sender);
    NSNumber *errorCode = [errorDict valueForKey:NSNetServicesErrorCode];
    
    switch ([errorCode intValue]) {
        case NSNetServicesActivityInProgress:
            NSLog(@"%s\n %@", __PRETTY_FUNCTION__, @"Service Resolution Currently in Progress. Please Wait.");
            break;
        case NSNetServicesTimeoutError:
            NSLog(@"%s\n %@", __PRETTY_FUNCTION__, @"Service Resolution Currently in Progress. Please Wait.");
            
            //service stop
            [sender stop];
            
            if (self.delegate && [self.delegate respondsToSelector:@selector(didFailPublishService:)]) {
                [self.delegate didFailPublishService:errorDict];
            }
            
            break;
    }
}

- (void)netServiceDidResolveAddress:(NSNetService *)service {
    //    mDNSDetailViewController *sdvc = [self.storyboard instantiateViewControllerWithIdentifier:@"mDNSDetailViewController"];
    //    sdvc.selectedService = service;
    //
    //    [self.navigationController pushViewController:sdvc animated:YES];
}


#pragma mark - Reachability Notification
- (void)netReachabilityChanged:(id)notification {
    
    if (_reachability.currentReachabilityStatus == ReachableViaWiFi) {
        NSLog(@"%s\n currentReachabilityStatus = %zd", __PRETTY_FUNCTION__, _reachability.currentReachabilityStatus);
        [self performSelectorInBackground:@selector(startSearchBonjourServices) withObject:nil];
    }
}

- (void)dealloc {
    NSLog(@"%s", __PRETTY_FUNCTION__);
    [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:kReachabilityChangedNotification];
    
    [_reachability stopNotifier];
    [_netServiceBrowser stop];
}


#pragma mark - Singleton

+ (NetworkServiceHandler *)handler {
    
    static NetworkServiceHandler *sharedNetworkServiceHandler = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedNetworkServiceHandler = [[self alloc] init];
    });
    return sharedNetworkServiceHandler;
}

- (id)init {
    if (self = [super init]) {
        
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(netReachabilityChanged:) name:kReachabilityChangedNotification object:nil];
        
        _reachability = [Reachability reachabilityForLocalWiFi];
        [_reachability startNotifier];
    }
    return self;
}


@end
