/*
 * 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 "WXTracingManager.h"
#import "WXComponentFactory.h"
#import "WXModuleFactory.h"
#import "WXSDKManager.h"
#import "WXComponentFactory.h"
#import "WXModuleFactory.h"
#import "WXHandlerFactory.h"
#import "WXUtility.h"
#import "WXComponentManager.h"
#import "WXTracingProtocol.h"
#import "WXSDKEngine.h"


@implementation WXTracing

-(NSDictionary *)dictionary {
    return [NSDictionary dictionaryWithObjectsAndKeys:self.ref?:@"",@"ref",self.parentRef?:@"",@"parentRef",self.className?:@"",@"className",self.name?:@"",@"name",self.ph?:@"",@"ph",@(self.ts),@"ts",@(self.traceId),@"traceId",@(self.duration),@"duration",self.fName?:@"",@"fName",self.iid?:@"",@"iid",@(self.parentId)?:0,@"parentId",self.threadName?:@"",@"tName", nil];
}
@end

@implementation WXTracingTask

@end

@interface WXTracingManager()

@property (nonatomic) BOOL isTracing;
@property (nonatomic, strong) NSMutableDictionary *tracingTasks;  // every instance have a task
@property (nonatomic, copy) NSString *currentInstanceId;  // every instance have a task

@end

@implementation WXTracingManager


+ (instancetype) sharedInstance{
    
    static WXTracingManager *instance = nil;
    static dispatch_once_t once;
    
    dispatch_once(&once, ^{
        instance = [[WXTracingManager alloc] initPrivate];
    });
    
    return instance;
}

- (instancetype) initPrivate{
    self = [super init];
    if(self){
        self.isTracing = NO;
    }
    
    return self;
}

+(void)switchTracing:(BOOL )isTracing
{
    [WXTracingManager sharedInstance].isTracing = isTracing;
}

+(BOOL)isTracing
{
    return [WXTracingManager sharedInstance].isTracing;
}

+(void)startTracing:(WXTracing *)tracing
{
    if([self isTracing]){
        if(![WXTracingManager sharedInstance].tracingTasks){
            [WXTracingManager sharedInstance].tracingTasks = [NSMutableDictionary new];
        }
        if(![[WXTracingManager sharedInstance].tracingTasks objectForKey:tracing.iid]){
            WXTracingTask *task = [WXTracingTask new];
            task.iid = tracing.iid;
            [[WXTracingManager sharedInstance].tracingTasks setObject:task forKey:tracing.iid];
        }
        WXTracingTask *task = [[WXTracingManager sharedInstance].tracingTasks objectForKey:tracing.iid];
        if(task.bundleUrl.length == 0){
            if(tracing.bundleUrl.length>0){
                task.bundleUrl = tracing.bundleUrl;
            }
        }
        if(!task.tracings){
            task.tracings = [NSMutableArray new];
        }
        if(WXFloatEqual(tracing.ts,0)){
            NSTimeInterval time=[[NSDate date] timeIntervalSince1970]*1000;
            tracing.ts = time;
        }
        if(WXFloatEqual(tracing.duration,0)){
            tracing.duration = WXTracingDurationDefault;
        }
        if(![WXTracingEnd isEqualToString:tracing.ph]){ // end is should not update
            tracing.traceId = task.counter++;
        }
        if([WXTNetworkHanding isEqualToString:tracing.name] && [WXTracingBegin isEqualToString:tracing.ph]){
            task.tag = WXTNetworkHanding;
        }
        NSTimeInterval ts = [[NSDate date] timeIntervalSince1970]*1000;
        tracing.ts = ts ;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateTracings:task tracing:tracing];
        });
    }
}

+(void)setBundleJSType:(NSString *)jsBundleString instanceId:(NSString *)iid
{
    if([self isTracing] && iid.length >0){
        WXTracingTask *task = [[WXTracingManager sharedInstance].tracingTasks objectForKey:iid];
        if(jsBundleString.length >0){
            NSRange range = [jsBundleString rangeOfString:@"}"];
            if (range.location != NSNotFound) {
                NSString *searchStr =  [jsBundleString substringToIndex:range.location+range.length];
                if ([searchStr rangeOfString:@"Vue"].location != NSNotFound){
                    task.bundleJSType = @"Vue";
                }else if([searchStr rangeOfString:@"Rax"].location != NSNotFound){
                    task.bundleJSType = @"Rax";
                }else{
                    task.bundleJSType = @"Weex";
                }
            }
        }
    }
}

+(void)clearTracingData
{
    [WXTracingManager sharedInstance].tracingTasks = nil;
}

+(NSTimeInterval)getCurrentTime
{
    if([self isTracing]){
        return  [[NSDate date] timeIntervalSince1970]*1000;
    }
    return 0;
}

+(void)startTracingWithInstanceId:(NSString *)iid ref:(NSString*)ref className:(NSString *)className name:(NSString *)name phase:(NSString *)phase functionName:(NSString *)functionName options:(NSDictionary *)options
{
    if([self isTracing]){
        WXTracing *tracing = [WXTracing new];
        tracing.parentId = -1;
        if(ref.length>0){
            tracing.ref = ref;
        }else {
            tracing.ref = @"";
        }
        if(className.length>0){
            tracing.className = className;
        }else {
            tracing.className = @"";
        }
        if(name.length>0){
            tracing.name = name;
        }
        if(functionName.length>0){
            tracing.fName = functionName;
        }
        if(phase.length>0){
            tracing.ph = phase;
        }
        if(iid.length>0){
            tracing.iid = iid;
        }
        
        if(options && options[@"ts"]){
            tracing.ts = [options[@"ts"] floatValue];
        }
        if(options && options[@"duration"]){
            tracing.duration =  [options[@"duration"] floatValue];
        }
        if(options && options[@"parentRef"]){
            tracing.parentRef = options[@"parentRef"];
        }
        if(options && options[@"bundleUrl"]){
            tracing.bundleUrl = options[@"bundleUrl"];
        }
        if(options && options[@"threadName"]){
            tracing.threadName = options[@"threadName"];
        }
        if(options && options[@"componentData"]){
            tracing.childrenRefs = [self getChildrenRefs:options[@"componentData"]];
        }
        [self startTracing:tracing];
    }
}

+ (NSMutableArray *)getChildrenRefs:(NSDictionary *)componentData
{
    NSMutableArray *mArray = [NSMutableArray new];
    [self recursively:mArray componentData:componentData];
    return mArray;
}

+(void)recursively:(NSMutableArray *)mArray componentData:(NSDictionary *)componentData
{
    if([componentData valueForKey:@"children"]){
        NSArray *children = [componentData valueForKey:@"children"];
        for(NSDictionary *subcomponentData in children){
            NSString *ref = [subcomponentData objectForKey:@"ref"];
            if(ref){
                [mArray addObject:ref];
            }
            [self recursively:mArray componentData:subcomponentData];
        }
    }
}

+(WXTracing *)copyTracing:(WXTracing *)tracing
{
    WXTracing *newTracing = [WXTracing new];
    if(tracing.ref.length>0){
        newTracing.ref = tracing.ref;
    }
    if(tracing.parentRef.length>0){
        newTracing.parentRef = tracing.parentRef;
    }
    if(tracing.className.length>0){
        newTracing.className = tracing.className;
    }
    if(tracing.name.length>0){
        newTracing.name = tracing.name;
    }
    if(tracing.fName.length>0){
        newTracing.fName = tracing.fName;
    }
    if(tracing.ph.length>0){
        newTracing.ph = tracing.ph;
    }
    if(tracing.iid.length>0){
        newTracing.iid = tracing.iid;
    }
    if(tracing.parentId>0){
        newTracing.parentId = tracing.parentId;
    }
    if(tracing.traceId>0){
        newTracing.traceId = tracing.traceId;
    }
    if(tracing.ts>0){
        newTracing.ts = tracing.ts;
    }
    if(tracing.threadName.length>0){
        newTracing.threadName = tracing.threadName;
    }
    return newTracing;
}

+(NSString *)getclassName:(WXTracing *)tracing
{
    NSString *className = @"";
    if(tracing.ref.length>0 && tracing.name.length >0){
        Class cls = [WXComponentFactory classWithComponentName:tracing.name];
        className = NSStringFromClass(cls);
    }else if(tracing.name.length > 0){
        Class cls = [WXModuleFactory classWithModuleName:tracing.name];
        if(cls){
            className = NSStringFromClass(cls);
        }
    }
    return  className;
}

+(NSInteger )getParentId:(WXTracingTask *)task tracing:(WXTracing *)tracing
{
    NSMutableArray *tracings = task.tracings;
    if([tracing.threadName isEqualToString:WXTJSBridgeThread]) {
        return -1;
    }
    if(tracings && [tracings count]>0){
        for (NSInteger i = [tracings count] - 1; i >= 0; i--) {
            WXTracing *t = tracings[i];
//            if([t.threadName isEqualToString:WXTJSBridgeThread]&& [self compareRef:tracing.ref withTracing:t] && ([t.name isEqualToString:tracing.name] || [t.name isEqualToString:WXTJSCall])){
            if([t.threadName isEqualToString:WXTJSBridgeThread]&& [self compareRef:tracing.ref withTracing:t]){
                if([t.fName isEqualToString:tracing.fName]){
                    return (NSInteger)t.traceId;
                }
            }
        }
    }
    return -1;
}

+(BOOL)compareRef:(NSString *)ref withTracing:(WXTracing *)tracing
{
    if([tracing.ref isEqualToString:ref]){
        return YES;
    }
    if(tracing.childrenRefs && [tracing.childrenRefs count] > 0){
        for (NSString *childRef in tracing.childrenRefs) {
            if([childRef isEqualToString:ref]){
                return YES;
            }
        }
    }
    return NO;
}

+(void)updateTracings:(WXTracingTask *)task tracing:(WXTracing *)tracing
{
    if([WXTNetworkHanding isEqualToString:task.tag]){
        if([WXTExecJS isEqualToString:tracing.name]){
            NSMutableArray *tracings = task.tracings;
            [tracings enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(WXTracing *bTracing, NSUInteger idx, BOOL *stop) {
                if(([WXTNetworkHanding isEqualToString:bTracing.name] || [bTracing.ref isEqualToString:tracing.ref])&&[WXTracingBegin isEqualToString:bTracing.ph]){
                    WXTracing *newTracing = [self copyTracing:bTracing];
                    newTracing.iid = tracing.iid;
                    newTracing.ph = WXTracingEnd;
                    newTracing.ts = tracing.ts ;
                    newTracing.duration = newTracing.ts - bTracing.ts ;
                    bTracing.duration = newTracing.duration;
                    [task.tracings addObject:newTracing];
                    *stop = YES;
                }
            }];
            task.tag = WXTExecJS;
        }
    }
    
    if([WXTracingBegin isEqualToString:tracing.ph]){
        if(tracing.ref.length>0){
            WXPerformBlockOnComponentThread(^{
                WXSDKInstance *instance = [WXSDKManager instanceForID:task.iid];
                WXComponent *com = [instance componentForRef:tracing.ref];
                if(task.bundleUrl.length == 0){
                    task.bundleUrl = [instance.scriptURL absoluteString];
                }
                if(com.supercomponent){
                    tracing.parentRef = com.supercomponent.ref;
                }
                tracing.name = com.type;
                if(tracing.className.length == 0){
                    tracing.className = [self getclassName:tracing];
                }
            });
            if(tracing.parentId == -1){
                tracing.parentId = [self getParentId:task tracing:tracing];
            }
        } else {
            if(tracing.parentId == -1){
                tracing.parentId = [self getParentId:task tracing:tracing];
            }
        }
    
    }
    if([WXTracingEnd isEqualToString:tracing.ph]){  // deal end
        NSMutableArray *tracings = task.tracings;
        [tracings enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(WXTracing *bTracing, NSUInteger idx, BOOL *stop) {
            if(tracing.ref.length > 0 && bTracing.ref.length>0){
                if(![tracing.ref isEqualToString:bTracing.ref]){
                    return ;
                }
            }
            
            if([bTracing.fName isEqualToString:tracing.fName] &&[WXTracingBegin isEqualToString:bTracing.ph] ){
                tracing.iid = bTracing.iid;
                if(bTracing.ref.length > 0){
                    tracing.ref = bTracing.ref;
                }
                if(bTracing.parentRef.length > 0){
                    tracing.parentRef = bTracing.parentRef;
                }
                tracing.parentId = bTracing.parentId;
                tracing.duration = tracing.ts - bTracing.ts ;
                tracing.traceId = bTracing.traceId;
                tracing.threadName = bTracing.threadName;
                bTracing.duration = tracing.duration;
                tracing.name = bTracing.name;
                *stop = YES;
            }
        }];
    }
    
    [task.tracings addObject:tracing];
    if([@"renderFinish" isEqualToString:tracing.fName] && [WXTracingInstant isEqualToString:tracing.ph] && [WXTUIThread isEqualToString:tracing.threadName]) {
        [WXTracingManager commitTracing:task.iid];
    }
}

+(NSMutableDictionary *)getTracingData
{
    if(![self isTracing]){
        return nil;
    }
    
    return [WXTracingManager sharedInstance].tracingTasks;
}

+(NSDictionary *)getTacingApi
{
    if(![self isTracing]){
        return @{};
     }
    NSMutableDictionary *dict = [NSMutableDictionary new];
    NSMutableArray *componetArray = [NSMutableArray new];
    NSMutableArray *moduleArray = [NSMutableArray new];
    NSMutableArray *handleArray = [NSMutableArray new];
    NSDictionary *componentConfigs = [WXComponentFactory componentConfigs];
    void (^componentBlock)(id, id, BOOL *) = ^(id mKey, id mObj, BOOL * mStop) {
        NSMutableDictionary *componentConfig = [mObj mutableCopy];
        NSDictionary *cDict = [WXComponentFactory componentSelectorMapsWithName:componentConfig[@"name"]];
        if(cDict && [cDict count]>0 && [cDict[@"methods"] count]>0){
            [componentConfig setObject:cDict[@"methods"] forKey:@"methods"];
        }
        [componetArray addObject:componentConfig];
    };
    [componentConfigs enumerateKeysAndObjectsUsingBlock:componentBlock];
    if(componetArray && [componetArray count]>0){
        [dict setObject:componetArray forKey:@"componet"];
    }
    NSDictionary *moduleConfigs = [WXModuleFactory moduleConfigs];
    void (^moduleBlock)(id, id, BOOL *) = ^(id mKey, id mObj, BOOL * mStop) {
        NSDictionary *mDict = [WXModuleFactory moduleSelectorMapsWithName:mKey];
        NSMutableDictionary *subDict = [NSMutableDictionary new];
        [subDict setObject:mKey forKey:@"name"];
        [subDict setObject:mObj forKey:@"class"];
        if([mDict objectForKey:mKey]){
            [subDict setObject:[mDict objectForKey:mKey] forKey:@"methods"];
        }
        [moduleArray addObject:subDict];
    };
    [moduleConfigs enumerateKeysAndObjectsUsingBlock:moduleBlock];
    if(moduleArray && [moduleArray count]>0){
        [dict setObject:moduleArray forKey:@"module"];
    }
    
    NSDictionary *handleConfigs = [[WXHandlerFactory handlerConfigs] mutableCopy];
    void (^handleBlock)(id, id, BOOL *) = ^(id mKey, id mObj, BOOL * mStop) {
        NSMutableDictionary *subDict = [NSMutableDictionary new];
        [subDict setObject:mKey forKey:@"class"];
        [subDict setObject:NSStringFromClass([mObj class]) forKey:@"name"];
        [handleArray addObject:subDict];
    };
    [handleConfigs enumerateKeysAndObjectsUsingBlock:handleBlock];
    if(handleArray && [handleArray count]>0){
        [dict setObject:handleArray forKey:@"handle"];
    }
    
    return dict;
}

+ (void)commitTracing:(NSString *)instanceId
{
    if(![self isTracing]){
        return ;
    }
    id tracingHandle = [WXSDKEngine handlerForProtocol:@protocol(WXTracingProtocol)];
    if ([tracingHandle respondsToSelector:@selector(commitTracingInfo:)]){
        WXTracingTask *task = [[WXTracingManager sharedInstance].tracingTasks objectForKey:instanceId];
        if(task) {
            [tracingHandle commitTracingInfo:task];
        }
        
    }
}

+ (void)commitTracingSummaryInfo:(NSDictionary *)info withInstanceId:(NSString *)instanceId
{
    if(![self isTracing]){
        return ;
    }
    id tracingHandle = [WXSDKEngine handlerForProtocol:@protocol(WXTracingProtocol)];
    if ([tracingHandle respondsToSelector:@selector(commitTracingSummaryInfo:)]){
        if(info) {
            NSMutableDictionary *newInfo = [info mutableCopy];
            if(instanceId.length > 0){
                [newInfo setObject:instanceId forKey:@"instanceId"];
                [newInfo setObject:[[WXUtility getEnvironment] objectForKey:@"platform"] forKey:@"platform"];
            }
            [tracingHandle commitTracingSummaryInfo:newInfo];
        }
        
    }
}

+(void)destroyTraincgTaskWithInstance:(NSString *)instanceId
{
    if(![self isTracing]){
        return ;
    }
    WXTracingTask *task = [[WXTracingManager sharedInstance].tracingTasks objectForKey:instanceId];
    if(task){
        [[WXTracingManager sharedInstance].tracingTasks removeObjectForKey:instanceId];
    }
}

@end
