//
//  MKRRadioControlMaster.m
//  MaoKRadioPlayer
//
//  Created by yyqxiaoyin on 2019/4/3.
//  Copyright © 2019 Muzen. All rights reserved.
//

#import "MKRRadioControlMaster.h"
#import "MKRBTRadioControlManager.h"
#import "MKRWIFIRadioControlManager.h"
#import <objc/runtime.h>


@interface MKRRadioControlMaster ()
@property (nonatomic, strong) id<MKRPlayControlProtocol>currentManager;
@property (nonatomic, assign) struct objc_method_description *protocolMethodList;
@property (nonatomic, assign) unsigned int protocolMethodCount;
@property (nonatomic, strong) NSTimer *checkTimmer;
@property (nonatomic, strong) NSHashTable *listeners;
@property (nonatomic, strong) id<MKRUPnPDevice> currentDevice;
@end

@implementation MKRRadioControlMaster

- (instancetype)init{
    if (self) {
        self.currentManager = [MKRBTRadioControlManager shareManager];
        [self setUpTimmer];
    }
    return self;
}

+ (instancetype)shareMaster{
    static MKRRadioControlMaster *master = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        master = [[MKRRadioControlMaster alloc] init];
    });
    return master;
}

- (void)changeCurrentDevice:(id<MKRUPnPDevice>)device{
    self.currentDevice = device;
    self.currentManager = [MKRWIFIRadioControlManager shareManager];
    [MKRWIFIRadioControlManager shareManager].currentDevice = self.currentDevice;
}

- (void)addStatusListener:(id<MKRPlayResourceUpdateProtocol>)listener{
    if (![self.listeners containsObject:listener]){
        [self.listeners addObject:listener];
    }
}

- (void)removeStatusListener:(id<MKRPlayResourceUpdateProtocol>)listener{
    if ([self.listeners containsObject:listener]) {
        [self.listeners removeObject:listener];
    }
}

- (void)setUpTimmer{
    if (self.checkTimmer) {
        [self.checkTimmer invalidate];
        self.checkTimmer = nil;
    }
    self.checkTimmer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updatePlayStatus) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.checkTimmer forMode:NSRunLoopCommonModes];
    [self.checkTimmer fire];
}

- (void)updatePlayStatus{
    if (!self.listeners.count)
        return;
//    MKROneSong *oneSong = [self currentPlayingSong];
//    for (id<MKRPlayResourceUpdateProtocol>obj in self.listeners){
//        if ([obj respondsToSelector:@selector(resourceUpdate:)]){
//            [obj resourceUpdate:oneSong];
//        }
//    }

}

- (void)forwardInvocation:(NSInvocation *)invocation{
    SEL sel = invocation.selector;
    BOOL hasMethod = [self hasTheProtocolContainSEL:sel];
    if (hasMethod) {
        if ([self.currentManager respondsToSelector:sel]) {
            [invocation invokeWithTarget:self.currentManager];
        }
    }else{
        [super forwardInvocation:invocation];
    }
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
    BOOL hasMethod = [self hasTheProtocolContainSEL:sel];
    if (hasMethod) {
        NSObject *target = self.currentManager;
        return [target methodSignatureForSelector:sel];
    }else{
        return [super methodSignatureForSelector:sel];
        
    }
}

- (BOOL)respondsToSelector:(SEL)aSelector{
    Method method = class_getInstanceMethod([self class], aSelector);
    if (method == NULL) {
        return NO;
    }
    return YES;
}

- (BOOL)hasTheProtocolContainSEL:(SEL)sel{
    [self protocolMethodList];
    for (int i = 0; i<self.protocolMethodCount; i++) {
        struct objc_method_description method = self.protocolMethodList[i];
        if ([NSStringFromSelector(method.name) isEqualToString:NSStringFromSelector(sel)]) {
            return YES;
        }
    }
    return NO;
}

- (struct objc_method_description *)protocolMethodList{
    if (_protocolMethodList == NULL) {
        Protocol *playControlProtocol = objc_getProtocol("MKRPlayControlProtocol");
        _protocolMethodList = protocol_copyMethodDescriptionList(playControlProtocol, NO, YES, &_protocolMethodCount);
    }
    return _protocolMethodList;
}

- (NSHashTable *)listeners{
    if (!_listeners) {
        _listeners = [NSHashTable weakObjectsHashTable];
    }
    return _listeners;
}

@end
