{{> ./httpClient_common}}

// courtesy of https://stackoverflow.com/questions/54122326/use-reviver-function-in-jquery-ajax-requests
$.ajaxSetup({
  converters: {
    // default was jQuery.parseJSON
    "text json": (data: string) => JSON.parse(data, jsonReviver),
  }
});

export const defaultHeaders: {
    Authorization?: string, 
	"User-Agent"?: string,
} = {};

export interface IApiGlobalConfig {
    basePath: string
    extraAjaxSettings: Partial<JQueryAjaxSettings>
}

export const globalConfig:IApiGlobalConfig = {
    //please use webpack's DefinePlugin to define API_PATH_ROOT
    basePath: BASE_PATH,
    extraAjaxSettings: {}
}


export interface Authentication {
    /**
    * Apply authentication settings to header and query params.
    */
    applyToRequest(requestOptions: JQueryAjaxSettings): void;
}

export class OAuth implements Authentication {
    applyToRequest(requestOptions: JQueryAjaxSettings): void {
        requestOptions.headers = {
            ...requestOptions.headers,
            ...defaultHeaders
        }
    }
}

export class BaseApi {
    protected basePath = globalConfig.basePath;
    protected defaultHeaders : any = {};
    protected auth = new OAuth() as Authentication;

	/** Assert required */
	protected r(params: any, fieldNames: string[]) {
		for (const fieldName of fieldNames) {
			const value = params[fieldName];
			if (value === null || value === undefined) {
				throw new Error(`field: ${fieldName} required`);
			}
		}
	}

    protected ajax(
        method: AjaxMethod,
        localVarPath: string,
        queryParameters: any,
        bodyDict: any,
    ): Promise<any> {
        let url = this.basePath + localVarPath;
        const queryParams: {[k:string]: any} = {};
        for(const [key, val] of Object.entries(queryParameters)){
            if(typeof val !== "undefined"){
                queryParams[key] = formatParam(val);
            }
        }
        if(Object.keys(queryParams).length){
            url = url + "?" + $.param(queryParams);
        }
        let requestOptions: JQueryAjaxSettings = {
            ...globalConfig.extraAjaxSettings,
            url,
            type: method,
            headers: this.defaultHeaders,
            processData: false,
        };
        if (bodyDict && Object.keys(bodyDict).length) {
            requestOptions.data = JSON.stringify(bodyDict);
            requestOptions.contentType = "application/json; charset=utf-8";
        }
        this.auth.applyToRequest(requestOptions);
        return new Promise((resolve: any, reject: any) => {
            $.ajax(requestOptions).then(
                (data: any, textStatus: string, jqXHR: JQueryXHR) => resolve(data),
                (xhr: JQueryXHR, textStatus: string, errorThrown: string) => reject(xhr),
            );
        });
    }    
}
