# Copyright 2015 VMware, Inc.
# All rights reserved. -- VMware Confidential
"""
VMCAM patching module following the B2B patching principles
"""
import sys
import os
import json
import platform
import logging
import socket
import vcsa_utils

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

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

# Import patches python directory where all individual python module reside
sys.path.append(os.path.join(VMCAM_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"

@extend(Hook.Discovery)
def discover(ctx):
    '''DiscoveryResult discover(PatchContext sharedCtx) throw UserUpgradeError'''

    return vcsa_utils.getComponentDiscoveryResult("vmcam")

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

    return RequirementsResult(requirements, patchInfo, mismatches)

@extend(Hook.Validation)
def validate(ctx): #pylint: disable=W0613
    '''ValidationResult validate(PatchContext sharedCtx)'''
    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('Vmcam 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()
    # In case of common-vCSA-hook it should start all vCSA active services
    progressReporter.updateProgress(0, _(_T("vmcam.patch.begin", 'Start VMware vSphere Authentication Proxy patching')))

    LwIsStarted = utils.start_lwsmd()

    _doIncrementalPatching(ctx)

    if LwIsStarted:
        utils.stop_lwsmd()

    progressReporter.updateProgress(100, _(_T("vmcam.patch.complete", 'Patching VMware vSphere Authentication Proxy completed')))
