"use strict";

var devIp       = require("dev-ip");
var open        = require("opn");
var filePath    = require("path");
var portScanner = require("portscanner-plus");
var _           = require("lodash");
var UAParser    = require("ua-parser-js");

var parser      = new UAParser();

var utils = {
    /**
     * @param {Object} options
     * @returns {String|boolean} - the IP address
     */
    getHostIp: function (options) {

        var returnValue = devIp.getIp(null);

        if (options) {
            if (options.host && options.host !== "localhost") {
                return options.host;
            }
            if (options.detect === false || !devIp) {
                return false;
            }
        }

        if (Array.isArray(returnValue)) {
            returnValue = returnValue[0];
        }

        return returnValue || false;
    },
    /**
     * Take the path provided in options & transform into CWD for serving files
     * @param {String} [baseDir]
     * @returns {String}
     */
    getBaseDir: function (baseDir) {

        if (Array.isArray(baseDir)) {
            return baseDir;
        }

        var suffix = "";
        var validRoots = ["./", "/", "."];

        if (!baseDir || _.contains(validRoots, baseDir)) {
            return process.cwd();
        }

        if (baseDir.charAt(0) === "/") {
            suffix = baseDir;
        } else {
            if (/^.\//.test(baseDir)) {
                suffix = baseDir.replace(".", "");
            } else {
                suffix = "/" + baseDir;
            }
        }

        return process.cwd() + suffix;
    },
    /**
     * Set URL Options
     */
    setUrlOptions: function (port, options) {

        var urls = {};
        var scheme = (options.https && !options.proxy && !options.tunnel) ? "https" : "http";

        if (!options.online) {
            urls.local = utils.getUrl(scheme + "://localhost:" + port, options);
            return urls;
        }

        var external  = utils.xip(utils.getHostIp(options), options);

        var localhost = "localhost";

        if (options.xip) {
            localhost = "127.0.0.1";
        }

        var local = utils.xip(localhost, options);

        options.external = options.host = external;

        return utils.getUrls(external, local, scheme, port, options);
    },
    /**
     * Append a start path if given in options
     * @param {String} url
     * @param {Object} options
     * @returns {String}
     */
    getUrl: function (url, options) {

        var prefix = "/";
        var startPath = options.startPath;

        if (options.proxy && options.proxy.startPath) {
            startPath = options.proxy.startPath;
        }

        if (startPath) {
            if (startPath.charAt(0) === "/") {
                prefix = "";
            }
            url = url + prefix + startPath;
        }

        return url;
    },
    /**
     * @param {String} external
     * @param {String} local
     * @param {String} scheme
     * @param {number|string} port
     * @param {Object} options
     * @returns {{local: string, external: string}}
     */
    getUrls: function (external, local, scheme, port, options) {

        var urls = {
            local: utils.getUrl(utils._makeUrl(scheme, local, port), options)
        };

        if (external !== local) {
            urls.external = utils.getUrl(utils._makeUrl(scheme, external, port), options);
        }

        return urls;
    },
    /**
     * @param {String} scheme
     * @param {String} host
     * @param {Number} port
     * @returns {String}
     * @private
     */
    _makeUrl: function (scheme, host, port) {
        return scheme + "://" + host + ":" + port;
    },
    /**
     * Get ports
     * @param {Object} options
     * @returns {Q.promise}
     */
    getPorts: function (options) {

        var port  = options.port;
        var ports = options.ports; // backwards compatibility
        var max;

        if (ports) {
            port = ports.min;
            max  = ports.max;
        }

        return portScanner.getPorts(1, port, max);
    },
    /**
     * @param {String} ua
     * @returns {Object}
     */
    getUaString: function (ua) {
        return parser.setUA(ua).getBrowser();
    },
    /**
     * @param {String} filepath
     * @param {String} cwd
     * @returns {String}
     */
    resolveRelativeFilePath: function (filepath, cwd) {
        return filepath.replace(cwd + "/", "");
    },
    /**
     * @param {String} path
     * @returns {String}
     */
    getFileExtension: function (path) {
        return filePath.extname(path).replace(".", "");
    },
    /**
     * Open the page in browser
     * @param {String} url
     * @param {Object} options
     */
    openBrowser: function (url, options) {

        if (_.isString(options.open)) {
            if (options.urls[options.open]) {
                url = options.urls[options.open];
            }
        }

        if (options.open) {

            if (options.browser !== "default") {
                if (Array.isArray(options.browser)) {
                    options.browser.forEach(function (browser) {
                        utils.open(url, browser);
                    });
                } else {
                    utils.open(url, options.browser); // single
                }
            } else {
                utils.open(url);
            }
        }
    },
    /**
     * Wrapper for open module - for easier stubbin'
     * @param url
     * @param name
     */
    open: function (url, name) {
        open(url, name || null);
    },
    /**
     * @param {Boolean} kill
     * @param err
     * @param cb
     */
    fail: function (kill, err, cb) {
        if (kill) {
            if (cb && _.isFunction(cb)) {
                cb(err);
            }
            process.exit(1);
        }
    },
    /**
     * Add support for xip.io urls
     * @param {String} host
     * @param {Object} options
     * @returns {String}
     */
    xip: function (host, options) {
        if (options.xip) {
            return host + ".xip.io";
        }
        if (options.hostnameSuffix) {
            return host + options.hostnameSuffix;
        }
        return host;
    },
    /**
     * @param {String} string
     * @returns {string}
     */
    ucfirst: function (string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
    },
    /**
     * Determine if an array of file paths will cause a full page reload.
     * @param {Array} needles
     * @param {Array} haystack
     * @returns {Boolean}
     */
    willCauseReload: function (needles, haystack) {
        return needles.some(function (needle) {
            return !_.contains(haystack, require("path").extname(needle).replace(".", ""));
        });
    }
};

module.exports = utils;

@@ -6719,31 +6719,24 @@
 ystack, 
-require(%22p
+fileP
 ath
-%22)
 .extname

Use already defined module