/*
 * 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.
 */

(function () {
    "use strict";

    var GeneratorConnection     = require("../common/js/GeneratorConnection"),
        PreviewService          = require("./js/PreviewService"),
        PreviewGlobal           = require("../common/PreviewGlobal"),
        JSXRunner               = require("../common/JSXRunner"),
        IPCMessage              = require("preview-common/IPCMessage");

    var hasConnected            = PreviewGlobal.window.localStorage.getItem("hasConnected"),
        hasOpenedForArtboard    = PreviewGlobal.window.localStorage.getItem("hasOpenedForArtboard"),
        genconn,
        currentStatus,
        retryHandle;

    var W3Events = {
        ONLINE: "online",
        OFFLINE: "offline"
    };

    var connectionStatus  = IPCMessage.connectionStatus,
        cepEvents         = IPCMessage.cepEvents;

    // launch PSPanel
    function launchPSPanel() {
        if (!hasConnected && !hasOpenedForArtboard) {
            // only do this once
            hasOpenedForArtboard = true;
            PreviewGlobal.window.localStorage.setItem("hasOpenedForArtboard", hasOpenedForArtboard);
            
            // notify generator that we're auto-opening PSPanel
            genconn.sendMessage({
                messageType: IPCMessage.types.PANELOPENEDARTBOARD
            });

            // open the Preview panel (PSPanel)
            PreviewGlobal.csInterface.requestOpenExtension("com.adobe.preview.panel", "");
        }
    }

    // check if current document has any artboards.  If so, notify the PSPanel.
    function checkAndNotifyOnArtboards() {
        JSXRunner.runJSX("getArtboardCount", null, function(count) {
            if (count > 0) {
                // stop watching for new artboard activity
                PreviewGlobal.csInterface.removeEventListener("documentAfterActivate", checkAndNotifyOnArtboards);
                
                // launch the PSPanel
                launchPSPanel();
            }
        });
    }
    
    // start watching for any new artboard activity
    function startWatchForArtboardActivity() {
        // only watch for artboard activity if we are under first-run conditions
        if (!hasConnected && !hasOpenedForArtboard) {
            // setup event handlers to check for new artboard activity
            PreviewGlobal.csInterface.addEventListener("documentAfterActivate", checkAndNotifyOnArtboards);
        }
    }

    // handle IPC messages from the generator
    function _handleGeneratorMessage(message) {
        switch(message.payload.messageType) {
            case IPCMessage.types.DEVICECONNECTED:
                // remember if we've connected to the Preview app on a device at least once
                if (!hasConnected) {
                    hasConnected = true;
                    PreviewGlobal.window.localStorage.setItem("hasConnected", hasConnected);
                }
                break;
            default:
                // unknown message type
                console.log("com.adobe.preview/PSLoader: received unknown Generator message type: " + JSON.stringify(message.payload.messageType));
        }
    }

    function _sendPreviewServiceStartedMessage() {
        genconn.sendMessage({
            messageType: IPCMessage.types.PREVIEWSERVICESTARTED,
            accessToken: PreviewService.accessToken,
            accountGuid: PreviewService.accountGuid
        });
    }

    // initialize the connection to the generator-preview plugin
    function _connectToGenerator() {
        // connect to Generator
        genconn = GeneratorConnection.connectToGenerator();

        // event handler to receive messages from the generator
        genconn.on("message", _handleGeneratorMessage);

        // try to reopen the connection if it closes
        genconn.on("close", function () {
            setTimeout(genconn.establishConnection.bind(genconn), GeneratorConnection.CONNECTION_RETRY_DELAY);
        });

        genconn.on("started", function () {
            // initialize the connection w/ the generator
            genconn.sendMessage({
                messageType: IPCMessage.types.REGISTERCEP,
                extension: IPCMessage.clients.CEPID_PSLOADER
            });
            _sendPreviewServiceStartedMessage();
        });
    }

    function tryLoggingIn() {
        PreviewService.init();
    }

    function sendStatusToPanel(status) {
        var event = new PreviewGlobal.window.CSEvent(cepEvents.CONNECTION_STATUS, "APPLICATION");
        event.data = {
            currentStatus: currentStatus,
            newStatus: status
        };
        PreviewGlobal.csInterface.dispatchEvent(event);
    }

    function setConnectionStatus(status) {
        sendStatusToPanel(status);
        currentStatus = status;

        switch(currentStatus) {
        case connectionStatus.INITIALIZING:
        case connectionStatus.READY_TO_PAIR:
        case connectionStatus.LOGGING_IN:
        case connectionStatus.ERROR:
            break;
        case connectionStatus.ONLINE:
            if (PreviewService.enabled && !PreviewService.accessToken) {
                tryLoggingIn();
            } else if (PreviewService.accessToken) {
                setConnectionStatus(connectionStatus.READY_TO_PAIR);
            }
            break;
        case connectionStatus.NOT_LOGGED_IN:
            if (!retryHandle) {
                setTimeout(function () {
                    retryHandle = undefined;
                    tryLoggingIn(true);
                }, 30000);
            }
            break;
        case connectionStatus.OFFLINE:
            if (retryHandle) {
                clearTimeout(retryHandle);
                retryHandle = undefined;
            }
            break;
        default:
            console.log("com.adobe.preview/PSLoader: unknown status " + status);
        }
    }

    function init() {
        PreviewGlobal.csInterface.addEventListener(IPCMessage.cepEvents.PANEL_OPENED, function () {
            sendStatusToPanel(currentStatus);
        });

        _connectToGenerator();
	
        setTimeout(startWatchForArtboardActivity, 1000);  // delay a second to wait for generator to start first

        PreviewService.events.on(PreviewService.events.LOGGED_IN, function () {
            setConnectionStatus(connectionStatus.READY_TO_PAIR);
            _sendPreviewServiceStartedMessage();
        });
        PreviewService.events.on(PreviewService.events.LOGGING_IN, function () {
            setConnectionStatus(connectionStatus.LOGGING_IN);
        });
        PreviewService.events.on(PreviewService.events.NOT_LOGGED_IN, function () {
            if (PreviewService.accountGuid !== undefined) {
                PreviewService.accountGuid = undefined;
                PreviewService.accessToken = undefined;
                _sendPreviewServiceStartedMessage();
            }
            setConnectionStatus(connectionStatus.NOT_LOGGED_IN);
        });
        PreviewService.events.on(PreviewService.events.ERROR, function () {
            setConnectionStatus(connectionStatus.ERROR);
        });

        PreviewGlobal.window.addEventListener(W3Events.ONLINE, function () {
            setConnectionStatus(connectionStatus.ONLINE);
        });
        PreviewGlobal.window.addEventListener(W3Events.OFFLINE, function () {
            setConnectionStatus(connectionStatus.OFFLINE);
        });

        if (PreviewGlobal.window.navigator.onLine) {
            setConnectionStatus(connectionStatus.ONLINE);
        } else {
            setConnectionStatus(connectionStatus.OFFLINE);
        }

        PreviewGlobal.window.cep.util.registerExtensionUnloadCallback(function() {
            PreviewService.shutdown();
        });
    }

    init();

}());
