/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

#import <Foundation/Foundation.h>
#import "WXAnalyzerCenter.h"
#import "WXAnalyzerProtocol.h"
#import "WXAppMonitorProtocol.h"
#import "WXSDKManager.h"
#import "WXLog.h"
#import "WXTracingManager.h"
#import "WXAnalyzerCenter.h"
#import "WXAnalyzerCenter+Transfer.h"
#import "WXUtility.h"
#import "WXSDKInstance_performance.h"
#import "WXCoreBridge.h"
#import "WXBridgeManager.h"
#import "WXBridgeContext.h"


#define MODULE_WX_APM  @"wxapm"

@interface WXAnalyzerCenter ()
{
    BOOL _interactionLogSwitch;
}
@property (nonatomic, strong) NSMutableArray<WXAnalyzerProtocol> *analyzerList;
@property (nonatomic, assign) BOOL anzlyzerSwitch;
@end

@implementation WXAnalyzerCenter

+ (instancetype) sharedInstance{

    static WXAnalyzerCenter *instance = nil;
    static dispatch_once_t once;

    dispatch_once(&once, ^{
        instance = [[WXAnalyzerCenter alloc] init];
        instance.analyzerList= [NSMutableArray<WXAnalyzerProtocol> new];
        instance.anzlyzerSwitch = NO;
    });

    return instance;
}

+ (void) transferPerformance:(NSString*)instanceId withType:(NSString*) type andKey:(NSString*) key andValue:(id)value
{
    if (![self isOpen]) {
        return;
    }

    if ([self isInteractionLogOpen] && [type isEqualToString:@"stage"]) {
        WXLogDebug(@"wxInteractionAnalyzer : [client][stage],%@,%@,%@",instanceId,key,value);
    }

    NSMutableArray* analyzerList = [self getAnalyzerList];
    if (nil == analyzerList) {
        return;
    }
    
    NSDictionary* dic =  @{
                            @"group":MODULE_WX_APM,
                            @"module":instanceId,
                            @"type":type,
                            @"data":@{key:value}
                            };
    for (id analyzer in analyzerList) {
        if ([analyzer respondsToSelector:(@selector(transfer:))]){
            [analyzer performSelector:@selector(transfer:) withObject:dic];
        }
    }
}

+ (void) transferInteractionInfo:(WXComponent*)targetComponent
{
    if (![self isOpen]) {
        return;
    }
    NSMutableArray* analyzerList = [self getAnalyzerList];
    if (nil == analyzerList) {
        return;
    }
    
    long renderOriginDiffTime = [WXUtility getUnixFixTimeMillis] - targetComponent.weexInstance.performance.renderUnixTimeOrigin;
    
    NSDictionary* dic =  @{
                           @"group":MODULE_WX_APM,
                           @"module":targetComponent.weexInstance.instanceId,
                           @"type":@"wxinteraction",
                           @"data":@{
                                   @"renderOriginDiffTime":@(renderOriginDiffTime),
                                   @"type":targetComponent.type,
                                   @"ref":targetComponent.ref,
                                   @"style":targetComponent.styles,
                                   @"attrs":targetComponent.attributes
                                   }
                           };
    for (id analyzer in analyzerList) {
        if ([analyzer respondsToSelector:(@selector(transfer:))]){
            [analyzer performSelector:@selector(transfer:) withObject:dic];
        }
    }
    if ([self isInteractionLogOpen]) {
        WXLogDebug(@"wxInteractionAnalyzer : [client][wxinteraction]%@",dic);
    }
}

+(void)transErrorInfo:(WXJSExceptionInfo *)errorInfo
{
    if (![self isOpen] || !errorInfo) {
        return;
    }

    WXSDKInstance *instance = [WXSDKManager instanceForID:errorInfo.instanceId];
    if (!instance) {
        return;
    }
    NSMutableArray* analyzerList = [self getAnalyzerList];
    if (nil == analyzerList) {
        return;
    }

    NSDictionary *dic= @{
                         @"errorCode":errorInfo.errorCode?:@"-1",
                         @"errorGroup":@"",
                         @"errorMsg":errorInfo.exception?:@"unSetException",
                         @"instanceId":instance.instanceId,
                         @"url":[instance.scriptURL absoluteString]?:@"unSetscriptURL",
                         @"group":GROUP_ANALYZER,
                         @"module":MODULE_ERROR,
                         @"type":TYPE_JS_ERROR
                        };
    
    for (id analyzer in analyzerList) {
        if ([analyzer respondsToSelector:(@selector(transfer:))]){
            [analyzer performSelector:@selector(transfer:) withObject:dic];
        }
    }
}

+ (void) addWxAnalyzer:(id<WXAnalyzerProtocol>)handler
{
    if (!handler) {
        return;
    }
    [[WXAnalyzerCenter sharedInstance].analyzerList addObject:handler];
}

+ (void) rmWxAnalyzer:(id<WXAnalyzerProtocol>)handler
{
    if (!handler) {
        return;
    }
    [[WXAnalyzerCenter sharedInstance].analyzerList removeObject:handler];
}

+ (NSMutableArray<WXAnalyzerProtocol> *)getAnalyzerList
{
    return [WXAnalyzerCenter sharedInstance].analyzerList;
}


+ (void)setOpen:(BOOL)isOpen
{
    [WXAnalyzerCenter sharedInstance].anzlyzerSwitch = isOpen;
}

+ (BOOL)isOpen
{
     return [WXAnalyzerCenter sharedInstance].anzlyzerSwitch;
}

+(void) switchInteractionLog:(BOOL) isOpen
{
    if ([WXAnalyzerCenter sharedInstance]->_interactionLogSwitch == isOpen) {
        return;
    }
    [WXAnalyzerCenter sharedInstance]->_interactionLogSwitch = isOpen;
    [WXCoreBridge registerCoreEnv:@"switchInteractionLog" withValue:isOpen?@"true":@"false"];
#ifdef DEBUG
    [WXLog setLogLevel: isOpen?WXLogLevelDebug:WXLogLevelLog];
#else
     [WXLog setLogLevel: isOpen?WXLogLevelDebug:WXLogLevelWarning];
#endif

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    if ([WXSDKManager.bridgeMgr respondsToSelector:@selector(bridgeCtx)]) {
        id bridgeCtx = [WXSDKManager.bridgeMgr performSelector:@selector(bridgeCtx) withObject:nil];
        if (nil != bridgeCtx && [bridgeCtx respondsToSelector:@selector(callJSMethod:args:)]) {
            WXPerformBlockOnBridgeThread(^(){
                NSArray* args = @[isOpen?@(1):@(0)];
                [bridgeCtx performSelector:@selector(callJSMethod:args:) withObject:@"switchInteractionLog" withObject:args];
            });
        }
    }
#pragma clang diagnostic pop
}

+(BOOL) isInteractionLogOpen
{
    return [WXAnalyzerCenter sharedInstance]->_interactionLogSwitch;
}

@end
