"""
Created on 09/07/2014

@author: synerty
"""
from twisted.internet import defer
from twisted.internet.defer import (
    Deferred,
    DeferredList,
    succeed,
    inlineCallbacks,
)
from vortex.DeferUtil import vortexLogFailure
from vortex.Payload import Payload
from vortex.PayloadEndpoint import PayloadEndpoint
from vortex.PayloadEnvelope import PayloadEnvelope
from vortex.VortexFactory import VortexFactory

from peek_plugin_base.PeekVortexUtil import peekServerName

__author__ = "peek"

import logging

logger = logging.getLogger(__name__)

# -------------------------------------
# Software Update Handler for data from agents

# The filter we listen on
peekPlatformVersionFilt = {
    "plugin": "peak_platform",
    "key": "peek_platform.version.check",
}  # LISTEN / SEND


class PeekSwVersionPollHandler(object):
    PEEK_PLATFORM = "peek_platform"

    def __init__(self):
        self._startupDeferred = Deferred()
        self._ep = None

    def start(self):
        from peek_platform import PeekPlatformConfig

        if not PeekPlatformConfig.config.autoPackageUpdate:
            return succeed(True)

        self._ep = PayloadEndpoint(peekPlatformVersionFilt, self._process)

        d = VortexFactory.sendVortexMsg(
            vortexMsgs=Payload(filt=peekPlatformVersionFilt)
            .makePayloadEnvelope()
            .toVortexMsg(),
            destVortexName=peekServerName,
        )
        d.addErrback(vortexLogFailure, logger, consumeError=True)

        return self._startupDeferred

    def _process(self, payloadEnvelope: PayloadEnvelope, **kwargs):
        logger.info(payloadEnvelope.result)
        assert not payloadEnvelope.result  # result is None means success

        from peek_platform import PeekPlatformConfig

        platformUpdate = False
        deferredList = []

        for swVersionInfo in payloadEnvelope.tuples:
            if swVersionInfo.name == self.PEEK_PLATFORM:
                if (
                    PeekPlatformConfig.config.platformVersion
                    != swVersionInfo.version
                ):
                    logger.info(
                        "Recieved platform update new version is %s, we're %s",
                        swVersionInfo.version,
                        PeekPlatformConfig.config.platformVersion,
                    )
                    d = PeekPlatformConfig.peekSwInstallManager.update(
                        swVersionInfo.version
                    )
                    deferredList.append(d)

                    # Don't process any more, we'll update them when we restart.
                    platformUpdate = True
                    break

            else:
                installedPluginVer = PeekPlatformConfig.config.pluginVersion(
                    swVersionInfo.name
                )

                if installedPluginVer != swVersionInfo.version:
                    logger.info(
                        "Recieved %s update new version is %s, we're %s",
                        swVersionInfo.name,
                        swVersionInfo.version,
                        installedPluginVer,
                    )

                    d = PeekPlatformConfig.pluginSwInstallManager.update(
                        swVersionInfo.name, swVersionInfo.version
                    )
                    deferredList.append(d)

        if not self._startupDeferred:
            return

        if deferredList:
            if platformUpdate:
                self._startupDeferred.errback(
                    Exception("Startup stopped, Platform update and restart")
                )
            else:
                DeferredList(deferredList).chainDeferred(self._startupDeferred)

        else:
            logger.info("No update required")
            if self._startupDeferred:
                self._startupDeferred.callback(True)

        self._startupDeferred = None


peekSwVersionPollHandler = PeekSwVersionPollHandler()
