var url            = require("url");
var Immutable      = require("immutable");
var path           = require("path");

var weinreApp;

const WEINRE_NAME      = "weinre-debug";
const WEINRE_ID        = "#browsersync";
const WEINRE_ELEM_ID   = "__browser-sync-weinre__";

var weinreTargetUrl    = {
    protocol: "http:",
    pathname: "/target/target-script-min.js",
    hash: WEINRE_ID
};

var weinreClientUrl    = {
    protocol: "http:",
    pathname: "/client/",
    hash: WEINRE_ID
};

/**
 * Prepare weinre for later possible use.
 * @param ui
 */
function init (ui) {

    var hostUrl    = getHostUrl(ui, ui.bs);
    var weinrePort = ui.getOptionIn(["weinre", "port"]);

    weinreTargetUrl.hostname = hostUrl.hostname;
    weinreClientUrl.hostname = hostUrl.hostname;
    weinreClientUrl.port     = weinrePort;
    weinreTargetUrl.port     = weinrePort;

    ui.setOption(WEINRE_NAME, Immutable.fromJS({
        name:  WEINRE_NAME,
        active: false,
        url:    false,
        targetUrl: url.format(weinreTargetUrl),
        clientUrl: url.format(weinreClientUrl),
        port: weinrePort
    }));

    setWeinreClientUrl(ui, url.format(weinreClientUrl));

    var methods = {
        toggle: function (data) {
            toggleWeinre(ui.socket, ui.clients, ui, ui.bs, data);
        },
        event: function (event) {
            methods[event.event](event.data);
        }
    };

    return methods;
}

/**
 * Get a suitable host URL for weinre
 * @param ui
 * @param bs
 * @returns {*}
 */
function getHostUrl(ui, bs) {

    var url = bs.getOptionIn(["urls", "external"]);

    if (!url) {
        url = bs.getOptionIn(["urls", "local"]);
    }

    return require("url").parse(url);
}


/**
 * @param ui
 * @param weinreClientUrl
 */
function setWeinreClientUrl(ui, weinreClientUrl) {
    var weinre = ui.options.getIn(["clientFiles", "weinre"]).toJS();
    ui.setMany(function (item) {
        item.setIn(["clientFiles", "weinre", "hidden"], weinre.hidden.replace("%s", weinreClientUrl));
        return item;
    });
}

/**
 * @param socket
 * @param clients
 * @param ui
 * @param bs
 * @param value
 */
function toggleWeinre (socket, clients, ui, bs, value) {

    if (value !== true) {
        value = false;
    }

    if (value) {

        var _debugger = enableWeinre(ui, bs);

        // set the state of weinre
        ui.setMany(function (item) {
            item.setIn([WEINRE_NAME, "active"], true);
            item.setIn([WEINRE_NAME, "url"], _debugger.url);
            item.setIn([WEINRE_NAME, "active"], true);
            item.setIn(["clientFiles", "weinre", "active"], true);
        }, {silent: true});


        // Let the UI know about it
        socket.emit("ui:weinre:enabled", _debugger);

        var fileitem = {
            type: "js",
            src: ui.getOptionIn([WEINRE_NAME, "targetUrl"]),
            id: WEINRE_ELEM_ID
        };

        // Add the element to all clients
        ui.addElement(clients, fileitem);

        // Save for page refreshes
        //clientScripts = clientScripts.set("weinre", fileitem);

    } else {

        // Stop it
        disableWeinre(ui, bs);

        //clientScripts = clientScripts.remove("weinre");

        // Reset the state
        ui.setOptionIn([WEINRE_NAME, "active"], false, {silent: false}); // Force a reload here
        ui.setOptionIn(["clientFiles", "weinre", "active"], false); // Force a reload here

        // Let the UI know
        socket.emit("ui:weinre:disabled");

        // Reload all browsers to remove weinre elements/JS
        clients.emit("browser:reload");

    }
}

/**
 * Enable the debugger
 * @param ui
 * @param bs
 * @returns {{url: string, port: number}}
 */
function enableWeinre (ui, bs) {

    if (weinreApp && typeof weinreApp.destroy === "function") {
        weinreApp.destroy();
        weinreApp = undefined;
    }

    var port     = ui.getOptionIn([WEINRE_NAME, "port"]);

    var logger   = require(path.join(path.dirname(require.resolve("weinre")), "utils.js"));

    logger.log = function (message) {
        ui.logger.debug("[weinre]: %s", message);
    };

    var weinre   = require("weinre");
    var external = getHostUrl(ui, bs);

    weinreApp = weinre.run({
        httpPort: port,
        boundHost: external.hostname,
        verbose: false,
        debug: false,
        readTimeout: 5,
        deathTimeout: 15 });

    require("server-destroy")(weinreApp);

    return ui.options.get(WEINRE_NAME).toJS();
}

/**
 * @param ui
 * @returns {any|*}
 */
function disableWeinre (ui) {
    if (weinreApp) {
        weinreApp.close();
        weinreApp = false;
    }
    return ui.options.get(WEINRE_NAME).toJS();
}

module.exports.init         = init;
module.exports.toggleWeinre = toggleWeinre;
