# Copyright 2016 VMware, Inc.
# All rights reserved. -- VMware Confidential
"""
Integrate netdumper service with the B2B patching framework
"""
import sys
import os
import platform
import logging

from patch_specs import PatchContext
from extensions import extend, Hook
from l10n import msgMetadata as _T, localizedString as _
from reporting import getProgressReporter
import vcsa_utils
from . import netdumperUtils as utils

logger = logging.getLogger(__name__)
MY_PAYLOAD_DIR = os.path.dirname(__file__)

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

# Define all the patches in the increasing order by the version
patches = [
    ("6.5.0", "patch1")
]

_CURRENT_SOURCE_VERSION_FILE = 'sourceVersion'


def getLatestPatchVersion():
    return patches[-1][0]


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

    result = vcsa_utils.getComponentDiscoveryResult('netdumper')
    if not result or not result.patchable:
        # Netdumper should not be part of infrastructure B2B upgrade
        return None

    currentVersion = utils.getSourceVersion()
    if currentVersion > getLatestPatchVersion():
        # The latest available version is running.
        # Not needed to participate in the B2B upgrade
        logger.info('Latest patch applied(cur: %s; latest:%s)'
                    % (currentVersion, getLatestPatchVersion()))
        return None

    # Store the current version in the stageDirectory
    with open(getSourceVersionPersistenceLocation(ctx), "w") as f:
        f.write(currentVersion)

    return result


@extend(Hook.Requirements)
def collectRequirements(ctx):
    '''RequirementsResult collectRequirements(PatchContext sharedCtx)'''
    pass


@extend(Hook.Validation)
def validate(ctx):
    '''ValidationResult validate(PatchContext sharedCtx)'''
    pass


@extend(Hook.Prepatch)
def prePatch(ctx):
    '''void prePatch(PatchContext sharedCtx) throw UserUpgradeError'''
    pass


def _doIncrementalPatching(ctx):
    # Get the current version from the stageDirectory
    with open(getSourceVersionPersistenceLocation(ctx), "r") as f:
        currVersion = f.readline()

    assert(currVersion)
    logger.info('Current version: %s' % (currVersion))

    # NETDUMPER_PROPERTIES file is always overwriten. Reset the source version
    utils.setSourceVersion(currVersion)

    patchCurrentVersion = False
    for ver, modulePath in patches:
        patchCurrentVersion |= currVersion <= ver

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

    # Store the last patched version
    utils.setSourceVersion(ver)


def getSourceVersionPersistenceLocation(ctx):
    return os.path.join(ctx.stageDirectory, _CURRENT_SOURCE_VERSION_FILE)


@extend(Hook.Patch)
def patch(ctx):
    '''void patch(PatchContext sharedCtx) throw UserUpgradeError'''
    progressReporter = getProgressReporter()
    progressReporter.updateProgress(
        0, _(_T("netdumper.patch.begin", 'Starting Netdumper patching')))
    _doIncrementalPatching(ctx)
    progressReporter.updateProgress(
        100, _(_T("netdumper.patch.complete", 'Patching Netdumper completed')))
