/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright (c) 2014 Adobe Systems Incorporated. All rights reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */

/*jslint vars: true, node: true, plusplus: true, devel: true, nomen: true, indent: 4, bitwise: true */
"use strict";

var Q = require("q"),
    Strings = require("./LocStrings"),
    LocalPrefs = require("./utils/localPrefs.js"),
    fs = require("fs"),
    Path = require("path"),
    PathUtils = require("shared/PathUtils");

var pathExists = function (path) {
    return fs.existsSync(path);
};

/**
 * Tries to create a top level path only
 *
 * @param {string} path
 * return null
 * @throws will throw the native FS errors
 */
var createPath = function(path) {
    fs.mkdirSync(path);
};

var canCreateDirectory = function (path) {
    return Q.Promise(function (resolve, reject) {
        if (module.exports.pathExists(path)) {
            reject(new Error("Something exists there, do not create"));
        } else {
            resolve();
        }
    });
};

var createDirectory = function (path) {
    return Q.Promise(function (resolve, reject) {
        var result = global.cep.fs.makedir(path);
        if (result.err === global.cep.fs.NO_ERROR) {
            resolve();
        } else {
            reject(new Error("can not create:", result));
        }
    });
};

var deleteDirectory = function (path) {
    return Q.ninvoke(fs, "rmdir", path);
};

var promptForFolder = function (title, initialPath) {
    var allowMultipleSelection = false,
        chooseDirectory = true,
        fileTypes = "",
        friendlyFilePrefix = "",
        prompt = Strings.EXPORT_PROMPT,
        promise = Q.Promise(function (resolve, reject) {
            var result = global.cep.fs.showOpenDialogEx(allowMultipleSelection, chooseDirectory, title, initialPath, fileTypes, friendlyFilePrefix, prompt);
            if (result && result.data.length === 1 &&  result.data[0]) {
                resolve(result.data[0]);
            } else if (result && result.err === 0) {
                reject(new Error("cancel"));
            } else if (result) {
                reject(new Error("error: " + result.err));
            } else {
                reject(new Error("error: unknown"));
            }
        });

    return promise;
};

var promptForFolderInInitialPath = function (title, initialPath) {
    return Q.Promise(function (resolve, reject) {
        var createdFolder = false;
        module.exports.canCreateDirectory(initialPath).then(function () {
            return module.exports.createDirectory(initialPath);
        }).then(function () {
            createdFolder = true;
        }).finally(function () {
            var promise = module.exports.promptForFolder(title, initialPath);
            if (createdFolder) {
                promise.then(function (selectedPath) {
                    if (selectedPath.indexOf(initialPath) !== 0) {
                        module.exports.deleteDirectory(initialPath);
                    }
                    resolve(selectedPath);
                }, function (e) {
                    module.exports.deleteDirectory(initialPath).finally(reject.bind(null, e));
                });
            } else {
                promise.done(resolve, reject);
            }
        });
    });
};


var getLastExportPathForDoc = function (psdPath) {
    var pref = LocalPrefs.getMRUPref("lastExportPathMRU", {psd: psdPath});
    if (pref) {
        return pref.path;
    }

    return null;
};

var setLastExportPathForDoc = function (psdPath, path) {
    // TODO: Remove this function and associated functionality.
    // if (psdPath && path) {
    //     var mruKey = {psd: psdPath},
    //         mruItem = {psd: psdPath, path: path};
    //     LocalPrefs.setMRUPref("lastExportPathMRU", mruKey, mruItem);
    // }
};


var getExportDirectoryDefaults = function (docFileBaseName, docFileDirectory) {
    //default folder name is not localized because we want to match generator and such which also don't localize 
    //the actual folder name
    var defaultName = docFileBaseName + "-assets",
        isWin = global.csInterface.getOSInformation().indexOf("Windows") > -1,
        lastPathUsed = module.exports.getLastExportPathForDoc(Path.join(docFileDirectory, docFileBaseName)),
        finalName,
        finalParentDir,
        finalPath;

    if (lastPathUsed) {
        finalPath = lastPathUsed;
    } else {
        finalPath = Path.join(docFileDirectory, defaultName);
    }

    if (module.exports.pathExists(finalPath)) {
        finalParentDir = Path.dirname(finalPath);
        finalName = Path.basename(finalPath);
    } else {
        finalPath = docFileDirectory;
        finalParentDir = docFileDirectory;
        finalName = Path.basename(finalPath);
    }

    return {
        isWin: isWin,
        name: finalName,
        parentDir: finalParentDir,
        path: finalPath
    };
};

var promptForExportDirectory = function (docFileBaseName, docFileDirectory) {
    var defaults = module.exports.getExportDirectoryDefaults(docFileBaseName, docFileDirectory);
    return module.exports.promptForFolderInInitialPath(Strings.EXTRACT_TITLE, defaults.path).then(function(directory) {
        module.exports.setLastExportPathForDoc(Path.join(docFileDirectory, docFileBaseName), directory);
        return directory;
    });
};

var promptForExportDirectoryWithFolderName = function (docFileBaseName, docFileDirectory) {
    var defaults = module.exports.getExportDirectoryDefaults(docFileBaseName, docFileDirectory);

    if (!global.cep.fs.showSaveDialogEx || defaults.isWin) {
        return module.exports.promptForFolderInInitialPath(Strings.EXTRACT_TITLE, defaults.path);
    }
    var title = Strings.EXTRACT_TITLE,
        initialPath = defaults.parentDir,
        fileTypes = defaults.isWin ? ["*"] : "",
        friendlyFilePrefix = Strings.FOLDER,
        prompt = Strings.EXPORT_PROMPT,
        nameFieldLabel = Strings.EXTRACT_FOLDER_LABEL,
        promise = Q.Promise(function (resolve, reject) {
            var result = global.cep.fs.showSaveDialogEx(title, initialPath, fileTypes, defaults.name, friendlyFilePrefix, prompt, nameFieldLabel);
            if (result && result.data) {
                module.exports.setLastExportPathForDoc(Path.join(docFileDirectory, docFileBaseName), result.data);
                resolve(result.data);
            } else if (result && result.err === 0) {
                reject(new Error("cancel"));
            } else if (result) {
                reject(new Error("error: " + result.err));
            } else {
                reject(new Error("error: unknown"));
            }
        });
 
    return promise;
};

var promptForExportFile = function (docFileBaseName, assetBasename, ext, docFileDirectory) {
    var defaults = module.exports.getExportDirectoryDefaults(docFileBaseName, docFileDirectory);
    
    var title = Strings.EXPORT_SINGLE_FILE_TITLE,
        initialPath = defaults.path,
        fileTypes = defaults.isWin ? [ext] : "",
        friendlyFilePrefix = module.exports.formatExtensionForFilter(ext),
        prompt = Strings.EXPORT_PROMPT,
        defaultName = assetBasename + "." + ext,
        nameFieldLabel = Strings.EXPORT_AS_LABEL,
        promise = Q.Promise(function (resolve, reject) {
            var result = global.cep.fs.showSaveDialogEx(title, initialPath, fileTypes, defaultName, friendlyFilePrefix, prompt, nameFieldLabel),
                selectedPath = result ? result.data : null;
            if (selectedPath) {
                module.exports.setLastExportPathForDoc(Path.join(docFileDirectory, docFileBaseName), Path.dirname(selectedPath));
                selectedPath = PathUtils.addExtIfNeededWithoutCausingConflicts(selectedPath, ext);
                resolve(selectedPath);
            } else if (result && result.err === 0) {
                reject(new Error("cancel"));
            } else if (result) {
                reject(new Error("error: " + result.err));
            } else {
                reject(new Error("error: unknown"));
            }
        });
    
    return promise;
};

var formatExtensionForFilter = function(ext) {
    return ext.toUpperCase() + " (*." + ext.toLowerCase() + ")";
};

module.exports.promptForFolder = promptForFolder;
module.exports.promptForExportDirectory = promptForExportDirectory;
module.exports.promptForExportDirectoryWithFolderName = promptForExportDirectoryWithFolderName;
module.exports.promptForExportFile = promptForExportFile;
module.exports.pathExists = pathExists;
module.exports.createPath = createPath;
module.exports.canCreateDirectory = canCreateDirectory;
module.exports.createDirectory = createDirectory;
module.exports.deleteDirectory = deleteDirectory;
module.exports.promptForFolderInInitialPath = promptForFolderInInitialPath;
module.exports.getExportDirectoryDefaults = getExportDirectoryDefaults;
module.exports.getLastExportPathForDoc = getLastExportPathForDoc;
module.exports.setLastExportPathForDoc = setLastExportPathForDoc;
module.exports.formatExtensionForFilter = formatExtensionForFilter;
