import sys
import os
import json
import platform
import logging
import socket
import vcsa_utils

from . import utils
from extensions import extend, Hook
from patch_specs import DiscoveryResult, ValidationResult, Question, Mismatch, \
    Requirements, PatchInfo, RequirementsResult
from l10n import msgMetadata as _T, localizedString as _
from reporting import getProgressReporter

log = logging.getLogger(__name__)
VMCA_PAYLOAD_DIR = os.path.dirname(__file__)

# Import patches python directory where all individual python module reside
sys.path.append(os.path.join(VMCA_PAYLOAD_DIR, "patches"))
patches = [
]

def getUtil():
    if os.name == "nt":
        return utils.PatchUtilsWin()
    else:
        return utils.PatchUtilsLin()

def getCurrentVersion():
    return getUtil().getSourceVersion()

def getLatestVersion():
    if len(patches) > 0:
        return patches[-1][0]
    return "6.5.0.0"

def getChangesSummary():
    latestPatchScript = patches[-1][1]
    mod = __import__(latestPatchScript)
    changesSummary = None
    if hasattr(mod, 'getChanges'):
        changesSummary = mod.getChanges()

    return changesSummary

@extend(Hook.Discovery)
def discover(ctx):
    '''DiscoveryResult discover(PatchContext ctx) throw UserError'''
    if platform.system().lower() == "windows":
        # I don't want to take part in windows patching workflow
        return None

    return vcsa_utils.getComponentDiscoveryResult("vmca")

@extend(Hook.Requirements)
def collectRequirements(ctx):
    '''RequirementsResult collectRequirements(PatchContext ctx)'''
    mismatches = []
    requirements = Requirements()
    patchInfo = PatchInfo()

    try:
        requirements = Requirements(requiredDiskSpace={"/storage/core" :
                                                           getUtil().getRequiredDiskSpace()},
                                    questions=[],
                                    rebootRequired=False)
    except Exception: #pylint: disable=W0703
        log.exception("Cannot connect to VMWare Certificate Services")
        mismatches.append(Mismatch(text=_(_T("vmca.error.text",
                                             "Unable to connect to VMWare Certificate Services")),
                                   description=_(_T("vmca.error.description",
                                                    "VMware Certificate Service is down")),
                                   resolution=_(_T("vmca.error.resolution",
                                                   "Please check that VMware Certificate Service is running")),
                                   severity=Mismatch.ERROR))

    return RequirementsResult(requirements, patchInfo, mismatches)

@extend(Hook.Validation)
def validate(ctx):
    '''ValidationResult validate(PatchContext ctx)'''
    mismatches = []
    return ValidationResult(mismatches)

@extend(Hook.Prepatch)
def prePatch(ctx): #pylint: disable=W0613
    '''void prePatch(PatchContext sharedCtx) throw UserUpgradeError'''

def _doIncrementalPatching(ctx):
    utils = getUtil()
    currVersion = getCurrentVersion()
    log.info('Vmca current version: %s', currVersion)
    patchCurrentVersion = currVersion is None

    for ver, modulePath in patches:
        compResult = utils.versionCompare(currVersion, ver)
        patchCurrentVersion |= compResult < 0

        if patchCurrentVersion:
            log.info('Applying patch %s on version %s' % (ver, modulePath))
            mod = __import__(modulePath)
            mod.doPatching(ctx)
            log.info('Patch %s applied' % (modulePath))

    utils.setSourceVersion(getLatestVersion())

@extend(Hook.Patch)
def patch(ctx):
    '''void patch(PatchContext sharedCtx) throw UserUpgradeError'''
    utils = getUtil()

    progressReporter = getProgressReporter()

    progressReporter.updateProgress(0, _(_T("vmca.patch.begin",
                                            'Start VMWare Certificate Services patching')))
    LwIsStarted = utils.start_lwsmd()

    _doIncrementalPatching(ctx)

    if LwIsStarted:
        utils.stop_lwsmd()

    progressReporter.updateProgress(100, _(_T("vmca.patch.complete",
                                              'Patching VMWare Certificate Services completed')))
