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

"""
Collection of helper functions that use Lookup Service
"""

from lookup_service import LookupService

VMWARE_PRODUCT_ID = 'com.vmware.cis'
SSO_TYPE_ID = 'cs.identity'
EP_SSO_PROTOCOL = 'wsTrust'
EP_SSO_TYPE_ID = 'com.vmware.cis.cs.identity.sso'

EP_SSOADMIN_PROTOCOL = 'vmomi'
EP_SSOADMIN_TYPE_ID = "com.vmware.cis.cs.identity.admin"

VAPI_PRODUCT_ID = "com.vmware.cis"
VAPI_TYPE_ID = "cs.vapi"
EP_VAPI_PROTOCOL = "vapi.json.https.public"

ANALYTICS_SERVICE_PRODUCT = 'com.vmware.ph'
ANALYTICS_SERVICE_TYPE = 'phservice'
ANALYTICS_ENDPOINT_TYPE = 'com.vmware.ph.api'
ANALYTICS_STAGING_ENDPOINT_TYPE = 'com.vmware.phstg.api'
ANALYTICS_ENDPOINT_PROTOCOL = 'https'



def get_sso_admin_endpoint_url(ls_client):
    """
    Returns SsoAdmin endpoint URL

    :param ls_client: LookupService client
    :type ls_client: services.lookup_service.LookupService


    :return: SSO Admin endpoint URL
    :rtype: str
    """
    filter_criteria = LookupService.create_filter(
                                        product_id=VMWARE_PRODUCT_ID,
                                        service_type=SSO_TYPE_ID,
                                        ep_protocol=EP_SSOADMIN_PROTOCOL,
                                        ep_type=EP_SSOADMIN_TYPE_ID
                                        )

    sso_endpoints = ls_client.get_services_list\
        (filter_criteria=filter_criteria)

    if sso_endpoints:
        if sso_endpoints[0].serviceEndpoints:
            sso_admin_url = sso_endpoints[0].serviceEndpoints[0].url
            return sso_admin_url

    return None


def get_sts_url(ls_client):
    """
    Returns STS Endpoint URL

    :param ls_client: LookupService client
    :type ls_client: services.lookup_service.LookupService

    :return: STS Endpoint URL
    :rtype: str
    """
    filter_criteria = LookupService.create_filter(product_id=VMWARE_PRODUCT_ID,
                                                  service_type=SSO_TYPE_ID,
                                                  ep_protocol=EP_SSO_PROTOCOL,
                                                  ep_type=EP_SSO_TYPE_ID)

    sts_endpoints = ls_client.get_services_list(
        filter_criteria=filter_criteria)

    if sts_endpoints:
        if sts_endpoints[0].serviceEndpoints:
            sts_url = sts_endpoints[0].serviceEndpoints[0].url
            return sts_url

    return None


def _get_vapi_url(ls_client, nodeId=None):
    """
    Returns vAPI Endpoint URL, that is located on the machine
    with the specified node id.

    :param ls_client: LookupService client
    :type ls_client: services.lookup_service.LookupService

    :param nodeId: Node ID of a machine (either VCSA or PSC)
    :type nodeId: str
    """
    filter_criteria = LookupService.create_filter(product_id=VAPI_PRODUCT_ID,
                                                  service_type=VAPI_TYPE_ID,
                                                  ep_protocol=EP_VAPI_PROTOCOL)

    if nodeId:
        filter_criteria.nodeId = nodeId

    vapi_endpoints = ls_client.get_services_list\
        (filter_criteria=filter_criteria)

    if vapi_endpoints:
        if vapi_endpoints[0].serviceEndpoints:
            vapi_url = vapi_endpoints[0].serviceEndpoints[0].url
            return vapi_url

    return None


def get_local_vapi_url(ls_client, service):
    """
    Returns vAPI Endpoint URL.
    It will return this endpoint that is located on the same machine
    on which the provided service points to.

    :param ls_client: LookupService client
    :type ls_client: services.lookup_service.LookupService

    :param service: Either a VcService or SsoAdminService instance
    :type service:
    services.vc_service.VcService or services.sso_service.SsoAdminService

    :return: vAPI Endpoint URL
    :rtype: str
    """
    # Get nodeId of the vCenter or the PSC from
    # its registration and get services with only this
    vc_uuid = service.get_uuid()
    vc_registration = ls_client.get_service(vc_uuid)
    vc_node_id = vc_registration.nodeId

    vapi_url = _get_vapi_url(ls_client, vc_node_id)
    return vapi_url


def get_global_vapi_url(ls_client):
    """
    Returns the global vAPI endpoint.
    In case of MxN deployment this endpoint will always point to the PSC node.

    :param ls_client: LookupService client
    :type ls_client: services.lookup_service.LookupService

    :return: Global vAPI endpoint
    :rtype: str
    """
    vapi_url = _get_vapi_url(ls_client)
    return vapi_url


def get_analytics_api_url(ls_client, vc_service):
    '''
    Retrieve local Analytics service API endpoint from Lookup service

    :param ls_client: LookupService client
    :param vc_service: VCService client
    :return: analytics api local endpoint url
    :rtype: str
    '''
    vac_client_endpoint = None

    # Get nodeId of the vCenter from its registration
    vc_uuid = vc_service.get_uuid()
    vc_registration = ls_client.get_service(vc_uuid)
    vc_node_id = vc_registration.nodeId

    # Use the nodeId to find all products on this node
    filter_criteria = LookupService.create_filter(
        ANALYTICS_SERVICE_PRODUCT,
        ANALYTICS_SERVICE_TYPE,
        ANALYTICS_ENDPOINT_PROTOCOL,
        ANALYTICS_STAGING_ENDPOINT_TYPE)
    filter_criteria.nodeId = vc_node_id

    service_registrations = ls_client.get_services_list\
        (filter_criteria=filter_criteria)
    if (len(service_registrations) > 0 and service_registrations[0] and
            len(service_registrations[0].serviceEndpoints) > 0):
        for attr in \
            service_registrations[0].serviceEndpoints[0].endpointAttributes:
            if attr.key == 'cis.common.ep.localurl':
                vac_client_endpoint = attr.value.rstrip('*')
                break

    return vac_client_endpoint
