/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.FileUtilities = class FileUtilities {
    static screenshotString()
    {
        let date = new Date;
        let values = [
            date.getFullYear(),
            Number.zeroPad(date.getMonth() + 1, 2),
            Number.zeroPad(date.getDate(), 2),
            Number.zeroPad(date.getHours(), 2),
            Number.zeroPad(date.getMinutes(), 2),
            Number.zeroPad(date.getSeconds(), 2),
        ];
        return WI.UIString("Screen Shot %s-%s-%s at %s.%s.%s").format(...values);
    }

    static sanitizeFilename(filename)
    {
        return filename.replace(/:+/g, "-");
    }

    static inspectorURLForFilename(filename)
    {
        return "web-inspector:///" + encodeURIComponent(FileUtilities.sanitizeFilename(filename));
    }

    static save(saveData, forceSaveAs)
    {
        console.assert(saveData);
        if (!saveData)
            return;

        if (typeof saveData.customSaveHandler === "function") {
            saveData.customSaveHandler(forceSaveAs);
            return;
        }

        console.assert(saveData.content);
        if (!saveData.content)
            return;

        let url = saveData.url || "";
        let suggestedName = parseURL(url).lastPathComponent;
        if (!suggestedName) {
            suggestedName = WI.UIString("Untitled");
            let dataURLTypeMatch = /^data:([^;]+)/.exec(url);
            if (dataURLTypeMatch) {
                let fileExtension = WI.fileExtensionForMIMEType(dataURLTypeMatch[1]);
                if (fileExtension)
                    suggestedName += "." + fileExtension;
            }
        }

        if (typeof saveData.content === "string") {
            const base64Encoded = saveData.base64Encoded || false;
            InspectorFrontendHost.save(suggestedName, saveData.content, base64Encoded, forceSaveAs || saveData.forceSaveAs);
            return;
        }

        let fileReader = new FileReader;
        fileReader.addEventListener("loadend", () => {
            let dataURLComponents = parseDataURL(fileReader.result);

            const base64Encoded = true;
            InspectorFrontendHost.save(suggestedName, dataURLComponents.data, base64Encoded, forceSaveAs || saveData.forceSaveAs);
        });
        fileReader.readAsDataURL(saveData.content);
    }

    static import(callback, {multiple} = {})
    {
        let inputElement = document.createElement("input");
        inputElement.type = "file";
        inputElement.value = null;
        inputElement.multiple = !!multiple;
        inputElement.addEventListener("change", (event) => {
            callback(inputElement.files);
        });

        inputElement.click();

        // Cache the last used import element so that it doesn't get GCd while the native file
        // picker is shown, which would prevent the "change" event listener from firing.
        FileUtilities.importInputElement = inputElement;
    }

    static importText(callback, options = {})
    {
        FileUtilities.import((files) => {
            FileUtilities.readText(files, callback);
        }, options);
    }

    static importJSON(callback, options = {})
    {
        FileUtilities.import((files) => {
            FileUtilities.readJSON(files, callback);
        }, options);
    }

    static importData(callback, options = {})
    {
        FileUtilities.import((files) => {
            FileUtilities.readData(files, callback);
        }, options);
    }

    static async readText(fileOrList, callback)
    {
        await FileUtilities._read(fileOrList, async (file, result) => {
            await new Promise((resolve, reject) => {
                let reader = new FileReader;
                reader.addEventListener("loadend", (event) => {
                    result.text = reader.result;
                    resolve(event);
                });
                reader.addEventListener("error", reject);
                reader.readAsText(file);
            });
        }, callback);
    }

    static async readJSON(fileOrList, callback)
    {
        await WI.FileUtilities.readText(fileOrList, async (result) => {
            if (result.text && !result.error) {
                try {
                    result.json = JSON.parse(result.text);
                } catch (e) {
                    result.error = e;
                }
            }

            await callback(result);
        });
    }

    static async readData(fileOrList, callback)
    {
        await FileUtilities._read(fileOrList, async (file, result) => {
            await new Promise((resolve, reject) => {
                let reader = new FileReader;
                reader.addEventListener("loadend", (event) => {
                    let {mimeType, base64, data} = parseDataURL(reader.result);

                    // In case no mime type was determined, try to derive one from the file extension.
                    if (!mimeType || mimeType === "text/plain") {
                        let extension = WI.fileExtensionForFilename(result.filename);
                        if (extension)
                            mimeType = WI.mimeTypeForFileExtension(extension);
                    }

                    result.mimeType = mimeType;
                    result.base64Encoded = base64;
                    result.content = data;

                    resolve(event);
                });
                reader.addEventListener("error", reject);
                reader.readAsDataURL(file);
            });
        }, callback);
    }

    // Private

    static async _read(fileOrList, operation, callback)
    {
        console.assert(fileOrList instanceof File || fileOrList instanceof FileList);

        let files = [];
        if (fileOrList instanceof File)
            files.push(fileOrList);
        else if (fileOrList instanceof FileList)
            files = Array.from(fileOrList);

        for (let file of files) {
            let result = {
                filename: file.name,
            };

            try {
                await operation(file, result);
            } catch (e) {
                result.error = e;
            }

            await callback(result);
        }
    }
};
