#!/usr/bin/env python
# Copyright 2016-2020 VMware, Inc.
# All rights reserved. -- VMware Confidential

"""
    This script is a utility to be used by both day0 and b2b scripts
"""
import sys
import os
from os.path import join, abspath, dirname
import logging
import json

logger = logging.getLogger(__name__)

DEPLOYMENT_ROOT = abspath(join(dirname(__file__), os.pardir))
sys.path.append(join(DEPLOYMENT_ROOT, "scripts/patches/libs/feature-state"))
import featureStateTarget
# do not call featureStateTarget.init() !!!
# init() will override all the values with the ones from
# /etc/vmware/vsphereFeatures/vsphereFeatures.cfg in source build

_FSSoverride = {}

# Try to load override file
FSS_OVERRIDES = "/etc/vmware/vsphereFeatures/b2b_fss_override.json"
FSS_FOLDER = os.path.abspath(os.path.join(FSS_OVERRIDES, os.pardir))

try:
    with open(FSS_OVERRIDES) as f:
        _FSSoverride = json.load(f)
except IOError:
    pass  # No such file: OK

# POD has special override for B2B due to privilege problems
POD_FSS_OVERRIDE = "/storage/vmware-pod/vsphereFeatures/b2b_fss_override.json"
if os.path.isfile(POD_FSS_OVERRIDE):
    with open(POD_FSS_OVERRIDE) as f:
        _FSSoverride.update(json.load(f))
    # Need to merge it in the file also
    if not os.path.exists(FSS_FOLDER):
        os.makedirs(FSS_FOLDER)
    with open(FSS_OVERRIDES, 'w') as f:
        json.dump(_FSSoverride, f)

def getTargetFSS(name):
    ''' Get FSS state for the target build. I.e. not the FSS state in this
        vCenter but FSS state as is set in the version being installed with this
        patch

    @param name: Name of the feature switch
    @type name: str

    @return: state as True, False or None (if set to None or there is no such
             switch)
    @rtype: bool

    '''
    if name in _FSSoverride:
        return _FSSoverride[name]
    # featureStateTarget.py defines all the feature switches as module-level
    # variables. So we use hasattr/getattr on module.
    if hasattr(featureStateTarget, name):
        return getattr(featureStateTarget, name)
    return None

def persistTargetFssChanges():
    ''' Persists the b2b_fss_override.json to the original CFD file, this is
    only done if the target fss has notion of CFG_FILE
    '''
    if hasattr(featureStateTarget, 'CFG_FILE'):
        cfgFile = featureStateTarget.CFG_FILE
    else:
        logger.debug('Production environment not changing FSS')
        return

    if not os.path.exists(cfgFile):
        logger.debug('Production environment not changing FSS')
        return

    if not _FSSoverride:
        logger.info("No FSS overrides")
        return

    copyOfFSS = _FSSoverride.copy()
    logger.info("Having FSS overrides: %s", copyOfFSS)
    result = []
    delimiter = '='

    def _generateNewEntry(key, val):
        val = 'enabled' if val else 'disabled'
        entry = '%s %s %s\n' % (key, delimiter, val)
        logger.info("Creating new entry: %s", entry)
        return entry

    with open(cfgFile, 'r', encoding='utf-8') as fp:
        for line in fp:
            key = line.rstrip().split(delimiter, 1)[0].strip()
            val = line.rstrip().split(delimiter, 1)[1].strip()
            if key in copyOfFSS:
                result.append(_generateNewEntry(key, copyOfFSS[key]))
                del copyOfFSS[key]  # so it is not appended after that
            else:
                result.append(line)

    # Add any new FSS that does not exist
    for key, val in copyOfFSS.items():
        if hasattr(featureStateTarget, key):
            result.append(_generateNewEntry(key, val))

    # Drop last new line
    result = ''.join(result).rstrip('\n')

    with open(cfgFile, 'w', encoding='utf-8') as fp:
        fp.write(result)
