/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

/* global FileSystem */

const argscheck = require('cordova/argscheck');
const exec = require('cordova/exec');
const FileTransferError = require('./FileTransferError');
const ProgressEvent = require('cordova-plugin-file.ProgressEvent');

function newProgressEvent (result) {
    const pe = new ProgressEvent();
    pe.lengthComputable = result.lengthComputable;
    pe.loaded = result.loaded;
    pe.total = result.total;
    return pe;
}

function getUrlCredentials (urlString) {
    const credentialsPattern = /^https?:\/\/(?:(?:(([^:@/]*)(?::([^@/]*))?)?@)?([^:/?#]*)(?::(\d*))?).*$/;
    const credentials = credentialsPattern.exec(urlString);

    return credentials && credentials[1];
}

function getBasicAuthHeader (urlString) {
    let header = null;

    // This is changed due to MS Windows doesn't support credentials in http uris
    // so we detect them by regexp and strip off from result url
    // Proof: http://social.msdn.microsoft.com/Forums/windowsapps/en-US/a327cf3c-f033-4a54-8b7f-03c56ba3203f/windows-foundation-uri-security-problem

    if (window.btoa) {
        const credentials = getUrlCredentials(urlString);
        if (credentials) {
            const authHeader = 'Authorization';
            const authHeaderValue = 'Basic ' + window.btoa(credentials);

            header = {
                name: authHeader,
                value: authHeaderValue
            };
        }
    }

    return header;
}

let idCounter = 0;

/**
 * FileTransfer uploads a file to a remote server.
 * @constructor
 */
const FileTransfer = function () {
    this._id = ++idCounter;
    this.onprogress = null; // optional callback
};

/**
 * Given an absolute file path, uploads a file on the device to a remote server
 * using a multipart HTTP request.
 * @param filePath {String}           Full path of the file on the device
 * @param server {String}             URL of the server to receive the file
 * @param successCallback (Function}  Callback to be invoked when upload has completed
 * @param errorCallback {Function}    Callback to be invoked upon error
 * @param options {FileUploadOptions} Optional parameters such as file name and mimetype
 * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
 */
FileTransfer.prototype.upload = function (filePath, server, successCallback, errorCallback, options, trustAllHosts) {
    argscheck.checkArgs('ssFFO*', 'FileTransfer.upload', arguments);
    // check for options
    let fileKey = null;
    let fileName = null;
    let mimeType = null;
    let params = null;
    let chunkedMode = true;
    let headers = null;
    let httpMethod = null;
    const basicAuthHeader = getBasicAuthHeader(server);
    if (basicAuthHeader) {
        server = server.replace(getUrlCredentials(server) + '@', '');

        options = options || {};
        options.headers = options.headers || {};
        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
    }

    if (options) {
        fileKey = options.fileKey;
        fileName = options.fileName;
        mimeType = options.mimeType;
        headers = options.headers;
        httpMethod = options.httpMethod || 'POST';
        if (httpMethod.toUpperCase() === 'PUT') {
            httpMethod = 'PUT';
        } else {
            httpMethod = 'POST';
        }
        if (options.chunkedMode !== null || typeof options.chunkedMode !== 'undefined') {
            chunkedMode = options.chunkedMode;
        }
        if (options.params) {
            params = options.params;
        } else {
            params = {};
        }
    }

    const fail =
        errorCallback &&
        function (e) {
            const error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);
            errorCallback(error);
        };

    const self = this;
    const win = function (result) {
        if (typeof result.lengthComputable !== 'undefined') {
            if (self.onprogress) {
                self.onprogress(newProgressEvent(result));
            }
        } else {
            if (successCallback) {
                successCallback(result);
            }
        }
    };
    exec(win, fail, 'FileTransfer', 'upload', [
        filePath,
        server,
        fileKey,
        fileName,
        mimeType,
        params,
        trustAllHosts,
        chunkedMode,
        headers,
        this._id,
        httpMethod
    ]);
};

/**
 * Downloads a file form a given URL and saves it to the specified directory.
 * @param source {String}          URL of the server to receive the file
 * @param target {String}         Full path of the file on the device
 * @param successCallback (Function}  Callback to be invoked when upload has completed
 * @param errorCallback {Function}    Callback to be invoked upon error
 * @param trustAllHosts {Boolean} Optional trust all hosts (e.g. for self-signed certs), defaults to false
 * @param options {FileDownloadOptions} Optional parameters such as headers
 */
FileTransfer.prototype.download = function (source, target, successCallback, errorCallback, trustAllHosts, options) {
    argscheck.checkArgs('ssFF*', 'FileTransfer.download', arguments);
    const self = this;

    const basicAuthHeader = getBasicAuthHeader(source);
    if (basicAuthHeader) {
        source = source.replace(getUrlCredentials(source) + '@', '');

        options = options || {};
        options.headers = options.headers || {};
        options.headers[basicAuthHeader.name] = basicAuthHeader.value;
    }

    let headers = null;
    if (options) {
        headers = options.headers || null;
    }

    const win = function (result) {
        if (typeof result.lengthComputable !== 'undefined') {
            if (self.onprogress) {
                return self.onprogress(newProgressEvent(result));
            }
        } else if (successCallback) {
            let entry = null;
            if (result.isDirectory) {
                entry = new (require('cordova-plugin-file.DirectoryEntry'))();
            } else if (result.isFile) {
                entry = new (require('cordova-plugin-file.FileEntry'))();
            }
            entry.isDirectory = result.isDirectory;
            entry.isFile = result.isFile;
            entry.name = result.name;
            entry.fullPath = result.fullPath;
            entry.filesystem = new FileSystem(
                result.filesystemName || (result.filesystem === window.PERSISTENT ? 'persistent' : 'temporary')
            );
            entry.nativeURL = result.nativeURL;
            successCallback(entry);
        }
    };

    const fail =
        errorCallback &&
        function (e) {
            const error = new FileTransferError(e.code, e.source, e.target, e.http_status, e.body, e.exception);
            errorCallback(error);
        };

    exec(win, fail, 'FileTransfer', 'download', [source, target, trustAllHosts, this._id, headers]);
};

/**
 * Aborts the ongoing file transfer on this object. The original error
 * callback for the file transfer will be called if necessary.
 */
FileTransfer.prototype.abort = function () {
    exec(null, null, 'FileTransfer', 'abort', [this._id]);
};

module.exports = FileTransfer;
