import {
    RequestOptions,
    HttpResponse
} from "@talentsoft-opensource/integration-widget-contract";
import { SecurityMode } from "../../securityModes/securityMode";
import { getSecurityMode } from "../../securityModes/factory";
var mime = require('mime-types');

function getFileNameFromContentDispostionHeader(header: string, contentType: string): string {
    let fileName = 'downloaded.' + mime.extension(contentType);
    if (header == null)
    {
        return fileName;
    }
    
    let contentDispostion = header.split(';');
    const fileNameToken = `filename=`;
    
    for (let thisValue of contentDispostion) {
        if (thisValue.trim().indexOf(fileNameToken) === 0) {
            fileName = decodeURIComponent(thisValue.trim().replace(fileNameToken, ''));
            break;
        }
    }
    return fileName;
}

export class ProxyClient {
    constructor(
        public secretKey: string,
        public login: string,
        public securityMode: SecurityMode = "directconnect"
    ) {}

    requestExternalResource = async (
        options: RequestOptions
    ): Promise<HttpResponse> => {
        const response = await fetch(
            `./proxy?url=${encodeURIComponent(options.url)}&secretkey=${
                this.secretKey
            }&login=${this.login}&securitymode=${this.securityMode}`,
            {
                method: options.verb,
                body: options.verb == "GET" ? undefined : options.body,
                headers: options.headers
            }
        );
        if (response.status === 200) {
            const payload: HttpResponse = await response.json();
            return payload;
        } else {
            const headers: Record<string, string> = {};
            response.headers.forEach((v, k) => {
                headers[k] = v;
            });
            return {
                status: response.status,
                headers,
                body: await response.text()
            };
        }
    };

    async downloadExternalResource(options: RequestOptions) {
        let response: Response;
        response = await fetch(`./download?url=${encodeURIComponent(options.url)}&secretkey=${
                this.secretKey
            }&login=${this.login}&securitymode=${this.securityMode}`,
            {
                method: options.verb,
                body: options.verb == "GET" ? undefined : options.body,
                headers: options.headers
            }
        )
        if (response.status === 200) {
            let result = await response.arrayBuffer();
            const newBlob = new Blob([result], { type: response.headers.get('content-type') ? response.headers.get('content-type')! : undefined });
            if (window.navigator && window.navigator.msSaveOrOpenBlob) {
                window.navigator.msSaveOrOpenBlob(newBlob);
            } else {
                const objUrl = window.URL.createObjectURL(newBlob);

                let link = document.createElement('a');
                link.href = objUrl;
                link.download = getFileNameFromContentDispostionHeader(response.headers.get('content-disposition')!, response.headers.get('content-type')!);
                link.click();

                setTimeout(() => { window.URL.revokeObjectURL(objUrl); }, 250);
            };
        }
    }

    getAutoConnectUrl(url: string) {
        const securityModeImpl = getSecurityMode(
            this.securityMode || "directconnect"
        );
        const params = securityModeImpl.getSecurityQueryParams(
            this.secretKey,
            this.login,
            new Date()
        );
        const urlObj = new URL(url);
        for (var p in params) {
            if (params.hasOwnProperty(p)) {
                urlObj.searchParams.append(p, params[p]);
            }
        }
        return urlObj.toString();
    }
}
