/*
 *
 * 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.
 *
*/

/*jshint -W030 */
/*global Windows, WinJS*/
/*global module, require*/

var FTErr = require('./FileTransferError'),
    ProgressEvent = require('cordova-plugin-file.ProgressEvent'),
    FileUploadResult = require('cordova-plugin-file.FileUploadResult'),
    FileProxy = require('cordova-plugin-file.FileProxy');

var appData = Windows.Storage.ApplicationData.current;

var LINE_START = "--";
var LINE_END = "\r\n";
var BOUNDARY = '+++++';

var fileTransferOps = [];

// Some private helper functions, hidden by the module
function cordovaPathToNative(path) {

    var cleanPath = String(path);
    // turn / into \\
    cleanPath = cleanPath.replace(/\//g, '\\');
    // turn  \\ into \
    cleanPath = cleanPath.replace(/\\\\/g, '\\');
    // strip end \\ characters
    cleanPath = cleanPath.replace(/\\+$/g, '');
    return cleanPath;
}

function nativePathToCordova(path) {
    return String(path).replace(/\\/g, '/');
}

function alreadyCancelled(opId) {
    var op = fileTransferOps[opId];
    return op && op.state === FileTransferOperation.CANCELLED;
}

function doUpload (upload, uploadId, filePath, server, successCallback, errorCallback) {
    if (alreadyCancelled(uploadId)) {
        errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));
        return;
    }

    // update internal TransferOperation object with newly created promise
    var uploadOperation = upload.startAsync();
    fileTransferOps[uploadId].promise = uploadOperation;

    uploadOperation.then(
        function (result) {
            // Update TransferOperation object with new state, delete promise property
            // since it is not actual anymore
            var currentUploadOp = fileTransferOps[uploadId];
            if (currentUploadOp) {
                currentUploadOp.state = FileTransferOperation.DONE;
                currentUploadOp.promise = null;
            }

            var response = result.getResponseInformation();
            var ftResult = new FileUploadResult(result.progress.bytesSent, response.statusCode, '');

            // if server's response doesn't contain any data, then resolve operation now
            if (result.progress.bytesReceived === 0) {
                successCallback(ftResult);
                return;
            }

            // otherwise create a data reader, attached to response stream to get server's response
            var reader = new Windows.Storage.Streams.DataReader(result.getResultStreamAt(0));
            reader.loadAsync(result.progress.bytesReceived).then(function (size) {
                ftResult.response = reader.readString(size);
                successCallback(ftResult);
                reader.close();
            });
        },
        function (error) {
            var source = nativePathToCordova(filePath);

            // Handle download error here.
            // Wrap this routines into promise due to some async methods
            var getTransferError = new WinJS.Promise(function (resolve) {
                if (error.message === 'Canceled') {
                    // If download was cancelled, message property will be specified
                    resolve(new FTErr(FTErr.ABORT_ERR, source, server, null, null, error));
                } else {
                    // in the other way, try to get response property
                    var response = upload.getResponseInformation();
                    if (!response) {
                        resolve(new FTErr(FTErr.CONNECTION_ERR, source, server));
                    } else {
                        var reader = new Windows.Storage.Streams.DataReader(upload.getResultStreamAt(0));
                        reader.loadAsync(upload.progress.bytesReceived).then(function (size) {
                            var responseText = reader.readString(size);
                            resolve(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, server, response.statusCode, responseText, error));
                            reader.close();
                        });
                    }
                }
            });

            // Update TransferOperation object with new state, delete promise property
            // since it is not actual anymore
            var currentUploadOp = fileTransferOps[uploadId];
            if (currentUploadOp) {
                currentUploadOp.state = FileTransferOperation.CANCELLED;
                currentUploadOp.promise = null;
            }

            // Report the upload error back
            getTransferError.then(function (transferError) {
                errorCallback(transferError);
            });
        },
        function (evt) {
            var progressEvent = new ProgressEvent('progress', {
                loaded: evt.progress.bytesSent,
                total: evt.progress.totalBytesToSend,
                target: evt.resultFile
            });
            progressEvent.lengthComputable = true;
            successCallback(progressEvent, { keepCallback: true });
        }
    );
}

function FileTransferOperation(state, promise) {
    this.state = state;
    this.promise = promise;
}

FileTransferOperation.PENDING = 0;
FileTransferOperation.DONE = 1;
FileTransferOperation.CANCELLED = 2;

var HTTP_E_STATUS_NOT_MODIFIED = -2145844944;

module.exports = {

/*
exec(win, fail, 'FileTransfer', 'upload', 
[filePath, server, fileKey, fileName, mimeType, params, trustAllHosts, chunkedMode, headers, this._id, httpMethod]);
*/
    upload: function (successCallback, errorCallback, options) {
        var filePath = options[0];
        var server = options[1];
        var fileKey = options[2] || 'source';
        var fileName = options[3];
        var mimeType = options[4];
        var params = options[5];
        // var trustAllHosts = options[6]; // todo
        // var chunkedMode = options[7]; // todo 
        var headers = options[8] || {};
        var uploadId = options[9];
        var httpMethod = options[10];

        var isMultipart = typeof headers["Content-Type"] === 'undefined';

        function stringToByteArray(str) {
            var byteCharacters = atob(str);
            var byteNumbers = new Array(byteCharacters.length);
            for (var i = 0; i < byteCharacters.length; i++) {
                byteNumbers[i] = byteCharacters.charCodeAt(i);
            }
            return new Uint8Array(byteNumbers);
        }

        if (!filePath || (typeof filePath !== 'string')) {
            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, null, server));
            return;
        }

        if (filePath.indexOf("data:") === 0 && filePath.indexOf("base64") !== -1) {
            // First a DataWriter object is created, backed by an in-memory stream where 
            // the data will be stored.
            var writer = Windows.Storage.Streams.DataWriter(new Windows.Storage.Streams.InMemoryRandomAccessStream());
            writer.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf8;
            writer.byteOrder = Windows.Storage.Streams.ByteOrder.littleEndian;

            var commaIndex = filePath.indexOf(",");
            if (commaIndex === -1) {
                errorCallback(new FTErr(FTErr.INVALID_URL_ERR, fileName, server, null, null, "No comma in data: URI"));
                return;
            }

            // Create internal download operation object
            fileTransferOps[uploadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);

            var fileDataString = filePath.substr(commaIndex + 1);

            // setting request headers for uploader
            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
            uploader.method = httpMethod;
            for (var header in headers) {
                if (headers.hasOwnProperty(header)) {
                    uploader.setRequestHeader(header, headers[header]);
                }
            }

            if (isMultipart) {
                // adding params supplied to request payload
                var multipartParams = '';
                for (var key in params) {
                    if (params.hasOwnProperty(key)) {
                        multipartParams += LINE_START + BOUNDARY + LINE_END;
                        multipartParams += "Content-Disposition: form-data; name=\"" + key + "\"";
                        multipartParams += LINE_END + LINE_END;
                        multipartParams += params[key];
                        multipartParams += LINE_END;
                    }
                }

                var multipartFile = LINE_START + BOUNDARY + LINE_END;
                multipartFile += "Content-Disposition: form-data; name=\"file\";";
                multipartFile += " filename=\"" + fileName + "\"" + LINE_END;
                multipartFile += "Content-Type: " + mimeType + LINE_END + LINE_END;

                var bound = LINE_END + LINE_START + BOUNDARY + LINE_START + LINE_END;

                uploader.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
                writer.writeString(multipartParams);
                writer.writeString(multipartFile);
                writer.writeBytes(stringToByteArray(fileDataString));
                writer.writeString(bound);
            } else {
                writer.writeBytes(stringToByteArray(fileDataString));
            }

            var stream;

            // The call to store async sends the actual contents of the writer 
            // to the backing stream.
            writer.storeAsync().then(function () {
                // For the in-memory stream implementation we are using, the flushAsync call 
                // is superfluous, but other types of streams may require it.
                return writer.flushAsync();
            }).then(function () {
                // We detach the stream to prolong its useful lifetime. Were we to fail 
                // to detach the stream, the call to writer.close() would close the underlying 
                // stream, preventing its subsequent use by the DataReader below. Most clients 
                // of DataWriter will have no reason to use the underlying stream after 
                // writer.close() is called, and will therefore have no reason to call
                // writer.detachStream(). Note that once we detach the stream, we assume 
                // responsibility for closing the stream subsequently; after the stream 
                // has been detached, a call to writer.close() will have no effect on the stream.
                stream = writer.detachStream();
                // Make sure the stream is read from the beginning in the reader 
                // we are creating below.
                stream.seek(0);
                // Most DataWriter clients will not call writer.detachStream(), 
                // and furthermore will be working with a file-backed or network-backed stream, 
                // rather than an in-memory-stream. In such cases, it would be particularly 
                // important to call writer.close(). Doing so is always a best practice.
                writer.close();

                if (alreadyCancelled(uploadId)) {
                    errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));
                    return;
                }

                // create download object. This will throw an exception if URL is malformed
                var uri = new Windows.Foundation.Uri(server);

                var createUploadOperation;
                try {
                    createUploadOperation = uploader.createUploadFromStreamAsync(uri, stream);
                } catch (e) {
                    errorCallback(new FTErr(FTErr.INVALID_URL_ERR));
                    return;
                }

                createUploadOperation.then(
                    function (upload) {
                        doUpload(upload, uploadId, filePath, server, successCallback, errorCallback);
                    },
                    function (err) {
                        var errorObj = new FTErr(FTErr.INVALID_URL_ERR);
                        errorObj.exception = err;
                        errorCallback(errorObj);
                    });
            });

            return;
        }

        if (filePath.substr(0, 8) === "file:///") {
            filePath = appData.localFolder.path + filePath.substr(8).split("/").join("\\");
        } else if (filePath.indexOf('ms-appdata:///') === 0) {
            // Handle 'ms-appdata' scheme
            filePath = filePath.replace('ms-appdata:///local', appData.localFolder.path)
                               .replace('ms-appdata:///temp', appData.temporaryFolder.path);
        } else if (filePath.indexOf('cdvfile://') === 0) {
            filePath = filePath.replace('cdvfile://localhost/persistent', appData.localFolder.path)
                               .replace('cdvfile://localhost/temporary', appData.temporaryFolder.path);
        }

        // normalize path separators
        filePath = cordovaPathToNative(filePath);

        // Create internal download operation object
        fileTransferOps[uploadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);

        Windows.Storage.StorageFile.getFileFromPathAsync(filePath)
        .then(function (storageFile) {

            if (!fileName) {
                fileName = storageFile.name;
            }
            if (!mimeType) {
                // use the actual content type of the file, probably this should be the default way.
                // other platforms probably can't look this up.
                mimeType = storageFile.contentType;
            }

            if (alreadyCancelled(uploadId)) {
                errorCallback(new FTErr(FTErr.ABORT_ERR, nativePathToCordova(filePath), server));
                return;
            }

            // setting request headers for uploader
            var uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
            uploader.method = httpMethod;
            for (var header in headers) {
                if (headers.hasOwnProperty(header)) {
                    uploader.setRequestHeader(header, headers[header]);
                }
            }

            // create download object. This will throw an exception if URL is malformed
            var uri = new Windows.Foundation.Uri(server);

            var createUploadOperation;
            try {
                if (isMultipart) {
                    // adding params supplied to request payload
                    var transferParts = [];
                    for (var key in params) {
                        // Create content part for params only if value is specified because CreateUploadAsync fails otherwise
                        if (params.hasOwnProperty(key) && params[key] !== null && params[key] !== undefined && params[key].toString() !== "") {
                            var contentPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart();
                            contentPart.setHeader("Content-Disposition", "form-data; name=\"" + key + "\"");
                            contentPart.setText(params[key]);
                            transferParts.push(contentPart);
                        }
                    }

                    // Adding file to upload to request payload
                    var fileToUploadPart = new Windows.Networking.BackgroundTransfer.BackgroundTransferContentPart(fileKey, fileName);
                    fileToUploadPart.setHeader("Content-Type", mimeType);
                    fileToUploadPart.setFile(storageFile);
                    transferParts.push(fileToUploadPart);

                    createUploadOperation = uploader.createUploadAsync(uri, transferParts);
                } else {
                    createUploadOperation = WinJS.Promise.wrap(uploader.createUpload(uri, storageFile));
                }
            } catch (e) {
                errorCallback(new FTErr(FTErr.INVALID_URL_ERR));
                return;
            }

            createUploadOperation.then(
                function (upload) {
                    doUpload(upload, uploadId, filePath, server, successCallback, errorCallback);
                },
                function (err) {
                    var errorObj = new FTErr(FTErr.INVALID_URL_ERR);
                    errorObj.exception = err;
                    errorCallback(errorObj);
                }
            );
        }, function (err) {
            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, fileName, server, null, null, err));
        });
    },

    // [source, target, trustAllHosts, id, headers]
    download:function(successCallback, errorCallback, options) {
        var source = options[0];
        var target = options[1];
        var downloadId = options[3];
        var headers = options[4] || {};

        if (!target) {
            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR));
            return;
        }
        if (target.substr(0, 8) === "file:///") {
            target = appData.localFolder.path + target.substr(8).split("/").join("\\");
        } else if (target.indexOf('ms-appdata:///') === 0) {
            // Handle 'ms-appdata' scheme
            target = target.replace('ms-appdata:///local', appData.localFolder.path)
                           .replace('ms-appdata:///temp', appData.temporaryFolder.path);
        } else if (target.indexOf('cdvfile://') === 0) {
            target = target.replace('cdvfile://localhost/persistent', appData.localFolder.path)
                           .replace('cdvfile://localhost/temporary', appData.temporaryFolder.path);
        }
        target = cordovaPathToNative(target);

        var path = target.substr(0, target.lastIndexOf("\\"));
        var fileName = target.substr(target.lastIndexOf("\\") + 1);
        if (path === null || fileName === null) {
            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR));
            return;
        }
        // Download to a temp file to avoid the file deletion on 304 
        // CB-7006 Empty file is created on file transfer if server response is 304
        var tempFileName = '~' + fileName;

        var download = null;

        // Create internal download operation object
        fileTransferOps[downloadId] = new FileTransferOperation(FileTransferOperation.PENDING, null);

        var downloadCallback = function(storageFolder) {
            storageFolder.createFileAsync(tempFileName, Windows.Storage.CreationCollisionOption.replaceExisting).then(function (storageFile) {

                if (alreadyCancelled(downloadId)) {
                    errorCallback(new FTErr(FTErr.ABORT_ERR, source, target));
                    return;
                }

                // if download isn't cancelled, contunue with creating and preparing download operation
                var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
                for (var header in headers) {
                    if (headers.hasOwnProperty(header)) {
                        downloader.setRequestHeader(header, headers[header]);
                    }
                }

                // create download object. This will throw an exception if URL is malformed
                try {
                    var uri = Windows.Foundation.Uri(source);
                    download = downloader.createDownload(uri, storageFile);
                } catch (e) {
                    // so we handle this and call errorCallback
                    errorCallback(new FTErr(FTErr.INVALID_URL_ERR));
                    return;
                }

                var downloadOperation = download.startAsync();
                // update internal TransferOperation object with newly created promise
                fileTransferOps[downloadId].promise = downloadOperation;

                downloadOperation.then(function () {

                    // Update TransferOperation object with new state, delete promise property
                    // since it is not actual anymore
                    var currentDownloadOp = fileTransferOps[downloadId];
                    if (currentDownloadOp) {
                        currentDownloadOp.state = FileTransferOperation.DONE;
                        currentDownloadOp.promise = null;
                    }

                    storageFile.renameAsync(fileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(function () {
                        var nativeURI = storageFile.path.replace(appData.localFolder.path, 'ms-appdata:///local')
                        .replace(appData.temporaryFolder.path, 'ms-appdata:///temp')
                        .replace(/\\/g, '/');

                        // Passing null as error callback here because downloaded file should exist in any case
                        // otherwise the error callback will be hit during file creation in another place
                        FileProxy.resolveLocalFileSystemURI(successCallback, null, [nativeURI]);
                    }, function(error) {
                        errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error));
                    });
                }, function(error) {

                    var getTransferError = new WinJS.Promise(function (resolve) {
                        // Handle download error here. If download was cancelled,
                        // message property will be specified
                        if (error.message === 'Canceled') {
                            resolve(new FTErr(FTErr.ABORT_ERR, source, target, null, null, error));
                        } else if (error && error.number === HTTP_E_STATUS_NOT_MODIFIED) {
                            resolve(new FTErr(FTErr.NOT_MODIFIED_ERR, source, target, 304, null, error));
                        } else {
                            // in the other way, try to get response property
                            var response = download.getResponseInformation();
                            if (!response) {
                                resolve(new FTErr(FTErr.CONNECTION_ERR, source, target));
                            } else {
                                var reader = new Windows.Storage.Streams.DataReader(download.getResultStreamAt(0));
                                reader.loadAsync(download.progress.bytesReceived).then(function (bytesLoaded) {
                                    var payload = reader.readString(bytesLoaded);
                                    resolve(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, response.statusCode, payload, error));
                                });
                            }
                        }
                    });
                    getTransferError.then(function (fileTransferError) {

                        // Update TransferOperation object with new state, delete promise property
                        // since it is not actual anymore
                        var currentDownloadOp = fileTransferOps[downloadId];
                        if (currentDownloadOp) {
                            currentDownloadOp.state = FileTransferOperation.CANCELLED;
                            currentDownloadOp.promise = null;
                        }

                        // Cleanup, remove incompleted file
                        storageFile.deleteAsync().then(function() {
                            errorCallback(fileTransferError);
                        });
                    });

                }, function(evt) {

                    var progressEvent = new ProgressEvent('progress', {
                        loaded: evt.progress.bytesReceived,
                        total: evt.progress.totalBytesToReceive,
                        target: evt.resultFile
                    });
                    // when bytesReceived == 0, BackgroundDownloader has not yet differentiated whether it could get file length or not,
                    // when totalBytesToReceive == 0, BackgroundDownloader is unable to get file length
                    progressEvent.lengthComputable = (evt.progress.bytesReceived > 0) && (evt.progress.totalBytesToReceive > 0);

                    successCallback(progressEvent, { keepCallback: true });
                });
            }, function(error) {
                errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error));
            });
        };

        var fileNotFoundErrorCallback = function(error) {
            errorCallback(new FTErr(FTErr.FILE_NOT_FOUND_ERR, source, target, null, null, error));
        };

        Windows.Storage.StorageFolder.getFolderFromPathAsync(path).then(downloadCallback, function (error) {
            // Handle non-existent directory
            if (error.number === -2147024894) {
                var parent = path.substr(0, path.lastIndexOf('\\')),
                    folderNameToCreate = path.substr(path.lastIndexOf('\\') + 1);

                Windows.Storage.StorageFolder.getFolderFromPathAsync(parent).then(function(parentFolder) {
                    parentFolder.createFolderAsync(folderNameToCreate).then(downloadCallback, fileNotFoundErrorCallback);
                }, fileNotFoundErrorCallback);
            } else {
                fileNotFoundErrorCallback();
            }
        });
    },

    abort: function (successCallback, error, options) {
        var fileTransferOpId = options[0];

        // Try to find transferOperation with id specified, and cancel its' promise
        var currentOp = fileTransferOps[fileTransferOpId];
        if (currentOp) {
            currentOp.state = FileTransferOperation.CANCELLED;
            currentOp.promise && currentOp.promise.cancel();
        } else if (typeof fileTransferOpId !== 'undefined') {
            // Create the operation in cancelled state to be aborted right away
            fileTransferOps[fileTransferOpId] = new FileTransferOperation(FileTransferOperation.CANCELLED, null);
        }
    }

};

require("cordova/exec/proxy").add("FileTransfer",module.exports);
