#!/usr/bin/env python

#
# Copyright 2019 VMware, Inc.  All rights reserved. -- VMware Confidential
#
"""
Patch script that does the following:
Change the metadata filename prefixes from certificatemanagement_ to com.vmware.vcenter_
for the certificatemanagement service in the lookupservice registration

"""
import logging
import os
import re
import sys
import warnings

vmware_python_path = os.getenv('VMWARE_PYTHON_PATH')
if vmware_python_path and os.path.exists(vmware_python_path):
    sys.path.append(vmware_python_path)

from cis.cisreglib import LookupServiceClient, SsoClient, _get_syscfg_info

logger = logging.getLogger(__name__)

# Suppress warnings coming from vmafd and identity imports.
with warnings.catch_warnings():
    warnings.simplefilter('ignore', RuntimeWarning)
    from identity.vmkeystore import VmKeyStore

CM_PRODUCT_ID = 'com.vmware.certificatemanagement'
CM_TYPE_ID = 'certificatemanagement'
MACHINE_NAME = 'machine'
VAPI_ENDPOINT_TYPE_ID = 'com.vmware.certificatemanagement.vapi'


def doPatching(ctx):
    logger.info("CertificateManagement patch: being executed %s", ctx)
    update_endpoints()

def update_endpoints():
    logger.info("Connecting to Lookup Service")
    ls_url, domain_name = _get_syscfg_info()
    ls_obj = LookupServiceClient(ls_url, retry_count=5)
    logger.info("Getting STS endpoint")
    sts_url, sts_cert_data = ls_obj.get_sts_endpoint_data()

    logger.info("Logging into SSO AdminClient as machine solution user")
    cert = None
    key = None

    try:
        with VmKeyStore('VKS') as ks:
            ks.load(MACHINE_NAME)
            cert = ks.get_certificate(MACHINE_NAME)
            key = ks.get_key(MACHINE_NAME)

        sso_client = SsoClient(sts_url, sts_cert_data, None, None, cert=cert,
                               key=key)
        ls_obj.set_sso_client(sso_client)

        logger.info("Fetching service Info for the CertificateManagement from Lookup Service")
        cert_mgmt_service_info = ls_obj.get_local_service_info(CM_PRODUCT_ID, CM_TYPE_ID)

        # Get the service info in the format the reregister API accepts
        service_info = ls_obj.service_content.serviceRegistration.Get(cert_mgmt_service_info.serviceId)
        mutable_spec = ls_obj._svcinfo_to_setspec(service_info)

        changeMetadataFileNames(mutable_spec)
        ls_obj.reregister_service(service_info.serviceId, mutable_spec)
        sso_client.cleanup()
    except BaseException as e:
        logger.error("Failed to reregister CertificateManagement with Lookup Service")
        raise e


def changeMetadataFileNames(mutable_spec):
    logger.info("Changing the metadata filename prefixes from certificatemanagement_ to com.vmware.vcenter_")
    for endpoint in mutable_spec.serviceEndpoints:
        if endpoint.endpointType.type == VAPI_ENDPOINT_TYPE_ID:
            for attr in endpoint.endpointAttributes:
                if "certificatemanagement_cli.json" in attr.value:
                    attr.value = attr.value.replace("certificatemanagement_cli.json", "com.vmware.vcenter_cli.json")
                elif "certificatemanagement_authorization.json" in attr.value:
                    attr.value = attr.value.replace("certificatemanagement_authorization.json",
                                                    "com.vmware.vcenter_authorization.json")
                elif "certificatemanagement_routing.json" in attr.value:
                    attr.value = attr.value.replace("certificatemanagement_routing.json",
                                                    "com.vmware.vcenter_routing.json")
                elif "certificatemanagement_metamodel.json" in attr.value:
                    attr.value = attr.value.replace("certificatemanagement_metamodel.json",
                                                    "com.vmware.vcenter_metamodel.json")
                elif "certificatemanagement_authentication.json" in attr.value:
                    attr.value = attr.value.replace("certificatemanagement_authentication.json",
                                                    "com.vmware.vcenter_authentication.json")

