//
//  Network.swift
//  GitHub
//
//  Created by 曹云霄 on 2017/12/5.
//  Copyright © 2017年 曹云霄. All rights reserved.
//
import Moya
import SwiftyJSON
import SVProgressHUD


struct Network {
    
    // 请求头
    static let publicParamEndpointPlugin = { (target: Service) -> Endpoint in
        let url = target.baseURL.absoluteString + target.path
        let endpoint = Endpoint(url: url, sampleResponseClosure: { .networkResponse(200, target.sampleData) }, method: target.method, task: target.task, httpHeaderFields: target.headers)
        return endpoint.adding(newHTTPHeaderFields: ["Content-Type" : "application/json;charset=utf-8"])
    }
    
    // 设置超时时间
    static let requestClosurePlugin = {(endpoint: Endpoint, closure: MoyaProvider<Service>.RequestResultClosure) -> Void in
        do {
           var urlRequest = try endpoint.urlRequest()
            urlRequest.timeoutInterval = 30
            closure(.success(urlRequest))
        } catch  {
            closure(.failure(MoyaError.requestMapping(endpoint.url)))
        }
    }

    // 监听请求状态
    static let networkActivityPlugin = NetworkActivityPlugin { (type,target)  in
        switch type {
        case .began:
            ShowLoadingView()
            UIApplication.shared.isNetworkActivityIndicatorVisible = true
        case .ended:
            HideLoadingView()
            UIApplication.shared.isNetworkActivityIndicatorVisible = false
        }
    }
    
    // 日志
    static let logPlugin =  NetworkLoggerPlugin(verbose: true, cURL: true, output: { (_ separator: String,_ terminator: String,_ items: Any...) in
        for item in items{
            print("---\((item as! String).replacingOccurrences(of: "\\", with: ""))")
        }
    }, requestDataFormatter: nil, responseDataFormatter: nil)
    
    // 公告请求对象
    static let provider = MoyaProvider<Service>(endpointClosure: publicParamEndpointPlugin,requestClosure: requestClosurePlugin,plugins: [networkActivityPlugin,logPlugin])

    // MARK: -取消所有请求
    static func cancelAllRequest() {
        provider.manager.session.invalidateAndCancel()
    }

    /// 公共请求方法
    ///
    /// - Parameters:
    ///   - target:  请求方法
    ///   - success: 请求成功
    ///   - error:   请求失败
    static func request(target: Service, success: @escaping (JSON) -> Void, failure: @escaping (MoyaError) -> Void) {
        provider.request(target) { result in
            switch result {
            /// 请求成功后先通过json解析数据，如果解析失败使用jsonString重试一次
            case let .success(response):
                do {
                    guard response.statusCode == 200 else {
                        failure(MoyaError.statusCode(response))
                        return
                    }
                    let json = try response.mapJSON()
                    success(JSON(json))
                } catch {
                    switch (error) {
                    case MoyaError.jsonMapping(response):
                        do {
                            let jsonString = try response.mapString()
                            success(JSON(jsonString))
                        }catch {
                            failure(error as! MoyaError)
                        }
                    default:
                        failure(error as! MoyaError)
                        break
                    }
                }
                break
            case let .failure(error):
                failure(error)
                break
            }
        }
    }
}
