#!/usr/bin/env python

#
# Copyright 2021 VMware, Inc.  All rights reserved. -- VMware Confidential
#
"""
Contains a patch script that is used when upgrading from a pre-M14v2 version of the
vSphere Client. The patch removes the user-defined plugin compatibility matrix.
This was done as a cleanup needed as part of Carbon Black remote plugin enablement on VMC:
https://confluence.eng.vmware.com/display/CIP/Project+Carbon#ProjectCarbon-M14UpgradeCleanup
"""

import logging
import os
import sys
from distutils.version import LooseVersion

if not os.environ['VMWARE_PYTHON_PATH'] in sys.path:
    sys.path.append(os.environ['VMWARE_PYTHON_PATH'])

from l10n import localizedString, msgMetadata

from .base import PatchBase
from .file_util import get_property_from_file
from .plugin_utils import remove_user_compatibility_matrix
from ..version_util import VSPHERE_UI_SOURCE_VERSION_PROP, VSPHERE_UI_PRE_UPGRADE_CONFIG_FILE, \
    isCloudVc, VSPHERE_UI_SOURCE_CLN_PROP

logger = logging.getLogger(__name__)


class Patch10(PatchBase):
    """
    Patch for removing the user defined compatibility matrix
    """

    def __init__(self):
        """
        Constructor
        Set the patch version and summary.
        """

        name = "patch_10"
        version = LooseVersion("10.0")
        summary = localizedString(msgMetadata(
            "vsphere.ui.patch10.summary",
            "Cleans up the user-defined plugin compatibility matrix on cloud vCenters when"
            "upgrading from a pre-M14v2 version"))
        PatchBase.__init__(self, name, version, summary)

    def should_patch(self, patch_context):
        """
        :param patch_context: Context given by the patch framework
        :type patch_context: patch_specs.PatchContext

        :return: Whether the patch should be executed or not
        :rtype: bool
        """
        if not isCloudVc():
            logger.info("Skipping Patch 10 as this is not a cloud VC.")
            return False
        pre_upgrade_cfg_file = os.path.join(str(patch_context.stageDirectory),
                                            VSPHERE_UI_PRE_UPGRADE_CONFIG_FILE)
        client_source_version_str = get_property_from_file(pre_upgrade_cfg_file,
                                                           VSPHERE_UI_SOURCE_VERSION_PROP)
        client_source_version = LooseVersion(client_source_version_str)

        # the RPM version of the vsphere-client for M14 releases
        m14_version = LooseVersion("7.0.2.00200")
        if client_source_version < m14_version:
            logger.info("Will apply Patch10 as the source H5 client version %s is before m14 (%s)."
                        % (client_source_version, m14_version))
            return True

        if client_source_version == m14_version:
            # this is a best effort to detect upgrade from m14v1 to m14v2+. Since
            # the main RPM version of m14vX releases is the same we'll try to detect it based on
            # the CLN which is part of the RPM version. This is unreliable, though - if there
            # is an express patch to m14v1 after m14v2 is released this logic will fail to detect
            # the m14v1 upgrade. This is unlikely to happen, however, and if it happens the
            # cleanup will be handled with a dedicated RTS script.
            logger.info("Client source version is from the m14 release line (%s)." % m14_version)

            # the CLN of the vsphere-h5client component used for the initial release of M14v1
            m14v1_cln = "8817641"
            client_source_cln = get_property_from_file(pre_upgrade_cfg_file,
                                                       VSPHERE_UI_SOURCE_CLN_PROP)
            if client_source_cln == m14v1_cln:
                logger.info("Will apply Patch10 as the source H5 client version is m14v1.")
                return True

        logger.info("Skipping Patch10 as the source H5 client version %s is after m14v1."
                    % client_source_version)
        return False

    def do_patching(self, patch_context):
        logger.info("Patch10: removing user plugin compatibility matrix...")
        remove_user_compatibility_matrix()
        logger.info("Patch10: done removing user plugin compatibility matrix...")
