# Copyright 2020 VMware, Inc.
# All rights reserved. -- VMware Confidential

import os
import sys
import logging
import shutil

TOKEN_SERVICE_CISREGSPEC_FILE = \
    "/usr/lib/vmidentity/install/tokenservice/tokenservice-ls-spec.properties"
TOKEN_SERVICE_CISREGSPEC_FILE_NEW = "%s.new" % TOKEN_SERVICE_CISREGSPEC_FILE
TOKEN_SERVICE_CISREGSPEC_FILE_UNREGISTER = "%s.unregister" % TOKEN_SERVICE_CISREGSPEC_FILE

logger = logging.getLogger(__name__)


def do_patching(ctx):

    # Only attempt the patching if the tokenservice-ls-spec.properties file
    # exists
    if not os.path.isfile(TOKEN_SERVICE_CISREGSPEC_FILE):
        logger.info('Service registration for tokenservice '
                    'does not exist: %s. Skipping patch_05.' %
                    TOKEN_SERVICE_CISREGSPEC_FILE)
        return

    # Only attempt the patching if the tokenservice-ls-spec.properties.new
    # file exists
    if not os.path.isfile(TOKEN_SERVICE_CISREGSPEC_FILE_NEW):
        logger.info('New service registration for tokenservice '
                    'does not exist: %s. Skipping patch_05.' %
                    TOKEN_SERVICE_CISREGSPEC_FILE_NEW)
        return

    # Only attempt the patching if the current configuration is before the
    # addition of vcenter_authentication
    data4 = getProperty(TOKEN_SERVICE_CISREGSPEC_FILE, 'endpoint0.data4.key')
    if data4 is None or 'tokenservice' not in data4:
        logger.info('Service registration spec for tokenservice is not the expected '
                    'version. endpoint0.data4.key = %s. Skipping '
                    'patch_05.' % data4)
        return

    # Only attempt the patching if the new configuration contains
    # vcenter_authentication metdata registration
    data4New = getProperty(TOKEN_SERVICE_CISREGSPEC_FILE_NEW, 'endpoint0.data4.key')
    if data4New is None or 'vc_authn' not in data4New:
        logger.info('Service new registration spec for tokenservice is not the '
                    'expected version. endpoint0.data4.key = %s. Skipping '
                    'patch_05.' % data4New)
        return

    # There is a bug in 7.0.0 GA where a File-Based Backup/Restore does not preserve
    # the tokenservice-ls-spec.properties file (this is fixed in 7.0U1 and above), which
    # means that this file may not include the service ID of the current tokenservice.
    # The service ID is required for the Lookup Service 'unregister' command, so if this
    # property doesn't exist, just skip the 'unregister'. The registration of the new
    # spec file should take care of updating the current data
    serviceid = getProperty(TOKEN_SERVICE_CISREGSPEC_FILE, 'cmreg.serviceid')
    if serviceid and len(serviceid) > 0:
        prepareCurrentSpecForRemoval()

    replaceCurrentSpecWithNewOne()


def getProperty(filepath, property):
    """
    Return the value of the property from a properties file
    """

    with open(filepath, 'rt') as f:
        for line in f:
            l = line.strip()
            if l and not l.startswith('#'):
                key_value = l.split('=')
                key = key_value[0].strip()
                if key == property:
                    return '='.join(key_value[1:]).strip()
    return None

def prepareCurrentSpecForRemoval():
    """
    prepares the current service registration to be removed OnSuccess by ../__init__.py
    """
    shutil.copy(TOKEN_SERVICE_CISREGSPEC_FILE, TOKEN_SERVICE_CISREGSPEC_FILE_UNREGISTER)

def replaceCurrentSpecWithNewOne():
    """
    prepares the new service registration to be performed OnSuccess by ../__init__.py
    """
    shutil.move(TOKEN_SERVICE_CISREGSPEC_FILE_NEW, TOKEN_SERVICE_CISREGSPEC_FILE)
