/*
 * 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 canSave(saveMode)
    {
        console.assert(Object.values(WI.FileUtilities.SaveMode).includes(saveMode), saveMode);
        return InspectorFrontendHost.canSave(saveMode);
    }

    static async save(saveMode, fileVariants, forceSaveAs)
    {
        console.assert(WI.FileUtilities.canSave(saveMode), saveMode);

        console.assert(fileVariants);
        if (!fileVariants) {
            InspectorFrontendHost.beep();
            return;
        }

        let isFileVariantsMode = saveMode === WI.FileUtilities.SaveMode.FileVariants;
        if (isFileVariantsMode)
            forceSaveAs = true;

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

        if (!isFileVariantsMode && !Array.isArray(fileVariants))
            fileVariants = [fileVariants];

        console.assert(Array.isArray(fileVariants), fileVariants);
        if (!Array.isArray(fileVariants)) {
            InspectorFrontendHost.beep();
            return;
        }

        let promises = fileVariants.map((fileVariant) => {
            let content = fileVariant.content;
            console.assert(content, fileVariant);
            if (!content)
                return null;

            let displayType = fileVariant.displayType || "";
            console.assert(!isFileVariantsMode || fileVariant.displayType, fileVariant);
            if (!fileVariant.displayType && isFileVariantsMode)
                return null;

            let suggestedName = fileVariant.suggestedName;
            if (!suggestedName) {
                let url = fileVariant.url || "";
                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;
                    }
                }
            }
            let url = WI.FileUtilities.inspectorURLForFilename(suggestedName);

            if (typeof content === "string") {
                return Promise.resolve({
                    displayType,
                    url,
                    content,
                    base64Encoded: !!fileVariant.base64Encoded,
                });
            }

            let wrappedPromise = new WI.WrappedPromise;
            let fileReader = new FileReader;
            fileReader.addEventListener("loadend", () => {
                wrappedPromise.resolve({
                    displayType,
                    url,
                    content: parseDataURL(fileReader.result).data,
                    base64Encoded: true,
                });
            });
            fileReader.readAsDataURL(content);
            return wrappedPromise.promise;
        });
        if (promises.includes(null)) {
            InspectorFrontendHost.beep();
            return;
        }

        let saveDatas = await Promise.all(promises);

        console.assert(isFileVariantsMode || saveDatas.length === 1, saveDatas);
        console.assert(!isFileVariantsMode || new Set(saveDatas.map((saveData) => saveData.displayType)).size === saveDatas.length, saveDatas);
        console.assert(!isFileVariantsMode || new Set(saveDatas.map((saveData) => WI.urlWithoutExtension(saveData.url))).size === 1, saveDatas);

        InspectorFrontendHost.save(saveDatas, !!forceSaveAs);
    }

    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);
        }
    }
};

// Keep in sync with `InspectorFrontendClient::SaveMode` and `InspectorFrontendHost::SaveMode`.
WI.FileUtilities.SaveMode = {
    SingleFile: "single-file",
    FileVariants: "file-variants",
};
