import { Singleton, Container, Scope, Inject } from "typescript-ioc";
import axios, { AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios';
const querystring = require('querystring');
const http = require('http')
const https = require('https')

/**
 * 基于Axios框架实现的Http工具
 * @author wufl2019@qq.com
 * @date 2020-06-23
 */
@Singleton
export class HttpClient {

    private readonly axios: AxiosInstance;

    constructor(_timeout: number = 5000) {
        this.axios = axios.create({
            timeout: _timeout
        });
        this.axios.defaults.httpAgent = new http.Agent({ timeout: _timeout });
        this.axios.defaults.httpsAgent = new https.Agent({ timeout: _timeout });
    }

    /**
     * @desc get请求
     * @param {String} path 请求api路径
     * @param {any} data 参数对象
     * @param {any} config 局部配置 {headers: {'X-Custom-Header': 'foobar'}}
     */
    async get(url: string, data: any = {}, config: any = {}): Promise<AxiosResponse> {
        return await this.axios.get(url, {
            params: data,
            ...config
        })
    }

    /**
     * @desc post表单请求
     * @param {String} path 请求api路径
     * @param {any} data 参数对象
     * @param {any} config 局部配置 {headers: {'X-Custom-Header': 'foobar'}}
     */
    async postForm(url: string, data: any = {}, config: any = {}): Promise<AxiosResponse> {
        if (!config['headers']) {
            config['headers'] = {}
        }
        config['headers']['content-type'] = 'application/x-www-form-urlencoded;charset=utf-8';
        return await this.axios.post(url, querystring.encode(data), config);
    }

    /**
     * @desc post JSON
     * @param {String} path 请求api路径
     * @param {any} data 参数对象
     * @param {any} config 局部配置 {headers: {'X-Custom-Header': 'foobar'}}
     */
    async postJson(url: string, params: any = {}, bodyObj: any = {}, config: any = {}): Promise<AxiosResponse> {
        let requestUrl = url
        if (!config['headers']) {
            config['headers'] = {}
        }
        config['headers']['content-type'] = 'application/json;charset=utf-8';
        if (params && Object.keys(params).length) {
            requestUrl = requestUrl + '?' + querystring.encode(params)
        }
        return await this.axios.post(requestUrl, bodyObj, config);
    }

    /**
     * @desc post 
     * @param {String} path 请求api路径
     * @param {any} data 参数对象
     * @param {any} config 局部配置 {headers: {'X-Custom-Header': 'foobar'}}
     */
    async post(url: string, data: any = {}, config: any = {}): Promise<AxiosResponse> {
        return await this.axios.post(url, data, config);
    }


    /**
     * @desc request 
     * @param {any} config AxiosRequestConfig
     */
    async request(config: AxiosRequestConfig = {}): Promise<AxiosResponse> {
        return await this.axios.request(config);
    }

}
