/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright (c) 2015 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, plusplus: true, devel: true, nomen: true, indent: 4, bitwise: true, node:true */
/*global require: true, $: true, exports: true, csInterface: true*/

(function () {
    "use strict";

    var FS = require("fs"),
        Path = require("path");

    var PathUtils = function () {};

    /**
     * @param {string} filePath
     * @param {string} ext Does not include dot.
     * @return {string}
     */
    PathUtils.prototype.addExtIfNeeded = function (filePath, desiredExt) {
        var actualExt = Path.extname(filePath);
        desiredExt = "." + desiredExt;

        // If filePath doesn't end in desiredExt, concat "." + desiredExt.
        if (actualExt.toLowerCase() !== desiredExt.toLowerCase()) {
            filePath += desiredExt;
        }

        return filePath;
    };

    /**
     * @param filePath
     * @param ext Does not include dot.
     * @return {string}
     */
    PathUtils.prototype.addExtIfNeededWithoutCausingConflicts = function (filePath, desiredExt) {
        var newPath = this.addExtIfNeeded(filePath, desiredExt);
        if (newPath != filePath) {
            // If the extension was actually added, make sure it didn't cause a file conflict. Otherwise, we don't want
            // to prevent intentional file conflicts resulting in overwrites.
            newPath = this.suffixPathNumericallyIfNeeded(newPath);
        }
        return newPath;
    };

    /**
     * @param {string} path Path to suffix if needed.
     * @param {function=} predicate A function that takes in a path and determines whether it should be suffixed. If the
     *      function returns a truthy value, the path will be suffixed. Default is FS.existsSync.
     * @return {string}
     */
    PathUtils.prototype.suffixPathNumericallyIfNeeded = function(path, predicate) {
        predicate = predicate || FS.existsSync;
        if (!predicate(path))
            return path;

        var ext = Path.extname(path),
            basename = Path.basename(path, ext),
            parentFolder = Path.dirname(path),
            resultBasename,
            resultFilename,
            resultPath,
            n = 1;

        do {
            resultBasename = basename + "-" + n;
            // Note that ext includes the "." here because we used Path.extname to get it.
            resultFilename = resultBasename + ext;
            resultPath = Path.join(parentFolder, resultFilename);
            n++;
        } while (predicate(resultPath));

        return resultPath;
    };

    /**
     * @param {string} destFolder
     * @param {string} basename
     * @param {string} ext Should not contain a dot.
     * @return {string}
     */
    PathUtils.prototype.buildPath = function (folder, basename, ext) {
        return this.addExtIfNeeded(Path.join(folder, basename), ext);
    };

    /**
     * If the path starts with a '~', converts that to the user's home directory in a platform-independent way.
     *
     * @param {string} path
     * @return {string}
     */
    PathUtils.prototype.resolveInitialTilde = function (path) {
        if (path[0] == "~") {
            return Path.join(this.getHomePath(), path.substr(1));
        }

        return path;
    };

    /**
     * Returns the user's home directory, in a platform-independent way.
     *
     * @return {string}
     */
    PathUtils.prototype.getHomePath = function () {
        // http://stackoverflow.com/questions/9080085/node-js-find-home-directory-in-platform-agnostic-way
        return this.getEnvVar("HOME") || this.getEnvVar("USERPROFILE") || "";
    };

    /**
     * Trying to mock process.env's properties directly leads to some odd behavior. Mock this function instead.
     *
     * @param {string} name
     */
    PathUtils.prototype.getEnvVar = function(name) {
        return process.env[name];
    };
    
    //TODO:we need to find a way to bring in the cc 2015 part. Its not currently supplied by generator.
    PathUtils.prototype.getPhotoshopPreferencesPath = function() {
        var PrefPath;
        //windows%appdata%\Adobe\Adobe Photoshop CC 2015\Adobe Photoshop CC 2015 Settings\
        //mac /Users/user/Library/Preferences/'
        if(this.getEnvVar("APPDATA")) {
            PrefPath = Path.join(this.getEnvVar("APPDATA"), "Adobe", "Adobe Photoshop CC 2015");
        } else {
            PrefPath = Path.join(this.getHomePath(), "Library", "Preferences");
        }
        return Path.join(PrefPath,  "Adobe Photoshop CC 2015 Settings");
    };
    
    PathUtils.prototype.getUserSettingPath = function() {
        return Path.join(this.getPhotoshopPreferencesPath(), "ExtractSettings.json");
    };

    module.exports = new PathUtils();
}());
