//
//  GMDebugTools.m
//  GMAlpha
//
//  Created by Q14 on 2018/11/5.
//  Copyright © 2018年 Gengmei. All rights reserved.
//

#import "GMDebugTools.h"
#import <Foundation/Foundation.h>
#import "Aspects.h"
#import <Objc/runtime.h>
#import <GMNetService/GMNetService-umbrella.h>
#import "AppDelegate.h"


@implementation GMDebugTools
#ifdef DEBUG
+ (void)load{
#ifndef DEBUG
    // 添加一条能在 release 环境下能提示错误的代码
    [Tools debugAlert:@"WMDebugTools 里的方法只能在 Debug 环境下运行"];
#endif
    //
    [self autoFillWeiboAccount];
    //    [self popToRoot];
    //    [self printURLRequest];
    
    [self disable_WebActionDisablingCALayerDelegate_willBeRemoved_warning];
    
    //    [self customRootViewController];
}

#pragma mark - 在调试时，避免webView因为不能响应某些方法而暂停运行带来的烦恼
+ (void)disable_WebActionDisablingCALayerDelegate_willBeRemoved_warning {
    Class class = NSClassFromString(@"WebActionDisablingCALayerDelegate");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    class_addMethod(class, @selector(willBeRemoved), willBeRemoved, NULL);
    class_addMethod(class, @selector(removeFromSuperview), removeFromSuperview, NULL);
    
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
    class_addMethod(class, @selector(setBeingRemoved:), setBeingRemoved, NULL);
#pragma clang diagnostic pop
    
#pragma clang diagnostic pop
}

void willBeRemoved()
{
    
}

void removeFromSuperview() {
    
}

id setBeingRemoved(id self, SEL selector, ...)
{
    return nil;
}

#pragma mark - 模拟器使用微博登录，自动填充指定的用户名密码
+ (void)autoFillWeiboAccount {
//    [NSClassFromString(@"WBSDKWebView") aspect_hookSelector:NSSelectorFromString(@"webViewDidFinishLoad:") withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) {
//        UIWebView *webview = [info.instance valueForKey:@"internalWebView"];
//        [webview stringByEvaluatingJavaScriptFromString:@"document.querySelector('#loginName').value='igiu_1988@126.com'"];
//        [webview stringByEvaluatingJavaScriptFromString:@"document.querySelector('#loginPassword').value='z4s-gJp-yGd-hpF'"];
//    } error:nil];
    
    // 打印 SSDKAuthView 的方法列表
    //    u_int               count;
    //    Method*    methods= class_copyMethodList(NSClassFromString(@"WBSDKWebView"), &count);
    //    for (int i = 0; i < count ; i++)
    //    {
    //        SEL name = method_getName(methods[i]);
    //        NSString *strName = [NSString  stringWithCString:sel_getName(name) encoding:NSUTF8StringEncoding];
    //        NSLog(@"%@",strName);
    //    }
    
    // 打印属性列表
    //    u_int               count;
    //    objc_property_t*    propertyList = class_copyPropertyList(NSClassFromString(@"WBSDKWebView"), &count);
    //    for (int i = 0; i < count ; i++)
    //    {
    //        const char *name = property_getName(propertyList[i]);
    //        NSString *strName = [NSString  stringWithCString:name encoding:NSUTF8StringEncoding];
    //        NSLog(@"%@",strName);
    //    }
}

#pragma mark - 两指同时点击页面，后退到 root controller
+ (void)popToRoot {
    
    [NSClassFromString(@"UIViewController") aspect_hookSelector:@selector(viewDidLoad) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info){
        
        UIViewController *controller = info.instance;
        // 这些UIKit库私有的controller我们不需要添加，另外还可以避免第三方输入法造成的crash
        NSArray *privateClass = @[@"_UIRemoteInputViewController", @"UICompatibilityInputViewController", @"UIInputWindowController", @"UIAlertController"];
        for (NSString *className in privateClass) {
            if ([controller isMemberOfClass:[NSClassFromString(className) class]]) {
                return ;
            }
        }
        
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backToRoot)];
        tap.numberOfTouchesRequired = 2;
        [controller.view addGestureRecognizer:tap];
    }error:NULL];
}

//+ (void)backToRoot{
//    [AppDelegate.navigation popToRootViewControllerAnimated:YES];
//}

#pragma mark - 打印 URLRequest
+ (void)printURLRequest {
    
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
    
    [NSClassFromString(@"WMNetService") aspect_hookSelector:@selector(sendRequestWithURLString:parameters:method:success:failed:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, NSString *url){
        NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:APIHOST]];
        for (NSHTTPCookie *cookie in cookies){
            NSLog(@"before request: %@, cookie name %@, cookie value %@", url, [cookie name],[cookie value]);
        }
    }error:NULL];
    
    [NSClassFromString(@"WMNetService") aspect_hookSelector:@selector(successWithTask:responseObject:success:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, NSURLSessionDataTask * task, NSObject *data){
        __weak NSURLRequest *request = task.currentRequest;
        NSString *requestBody = [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding];
        __weak NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
        NSLog(@"\nRequest:\n%@\nRequestBody:\n%@\nResponseHeader:%@\nRespondBody:\n%@\n", request.description, requestBody, response.allHeaderFields.description, data.description);
        
    }error:NULL];
    
    [NSClassFromString(@"WMNetService") aspect_hookSelector:@selector(failureWithTask:error:failed:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info, NSURLSessionDataTask * task){
        
        __weak NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
        __weak NSURLRequest *request = task.currentRequest;
        
        NSInteger statusCode = response.statusCode;
        
        NSLog(@"\nrequest: \n%@\nfailed: %ld\n", request.description, (long)statusCode);
        
        
    }error:NULL];
#pragma clang diagnostic pop
    
}


#pragma mark - 工具：打印某个 class 的所有方法
void dumpObjcMethods(Class clz) {
    
    unsigned int methodCount = 0;
    Method *methods = class_copyMethodList(clz, &methodCount);
    
    printf("Found %d methods on '%s'\n", methodCount, class_getName(clz));
    
    for (unsigned int i = 0; i < methodCount; i++) {
        Method method = methods[i];
        
        printf("\t'%s' has method named '%s' of encoding '%s'\n",
               class_getName(clz),
               sel_getName(method_getName(method)),
               method_getTypeEncoding(method));
        
        /**
         *  Or do whatever you need here...
         */
    }
    
    free(methods);
}


#endif
@end
