#
# Copyright 2017 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""
Some consul related convenience functions
"""

from structlog import get_logger
from consul import Consul
from random import randint
from nethelpers import get_my_primary_local_ipv4

log = get_logger()


def connect_to_consult(consul_endpoint):
    log.debug('getting-service-endpoint', consul=consul_endpoint)

    host = consul_endpoint.split(':')[0].strip()
    port = int(consul_endpoint.split(':')[1].strip())

    return Consul(host=host, port=port)


def verify_all_services_healthy(consul_endpoint, service_name=None,
                                number_of_expected_services=None):
    """
    Verify in consul if any service is healthy
    :param consul_endpoint: a <host>:<port> string
    :param service_name: name of service to check, optional
    :param number_of_expected_services number of services to check for, optional
    :return: true if healthy, false otherwise
    """

    def check_health(service):
        _, serv_health = consul.health.service(service, passing=True)
        return not serv_health == []

    consul = connect_to_consult(consul_endpoint)

    if service_name is not None:
        return check_health(service_name)

    services = get_all_services(consul_endpoint)

    items = services.keys()

    if number_of_expected_services is not None and \
                    len(items) != number_of_expected_services:
        return False

    for item in items:
        if not check_health(item):
            return False

    return True


def get_all_services(consul_endpoint):
    log.debug('getting-service-verify-health')

    consul = connect_to_consult(consul_endpoint)
    _, services = consul.catalog.services()

    return services


def get_all_instances_of_service(consul_endpoint, service_name):
    log.debug('getting-all-instances-of-service', service=service_name)

    consul = connect_to_consult(consul_endpoint)
    _, services = consul.catalog.service(service_name)

    for service in services:
        log.debug('service',
                  name=service['ServiceName'],
                  serviceid=service['ServiceID'],
                  serviceport=service['ServicePort'],
                  createindex=service['CreateIndex'])

    return services


def get_endpoint_from_consul(consul_endpoint, service_name):
    """
    Get endpoint of service_name from consul.
    :param consul_endpoint: a <host>:<port> string
    :param service_name: name of service for which endpoint
                         needs to be found.
    :return: service endpoint if available, else exit.
    """
    log.debug('getting-service-info', service=service_name)

    consul = connect_to_consult(consul_endpoint)
    _, services = consul.catalog.service(service_name)

    if len(services) == 0:
        raise Exception(
            'Cannot find service {} in consul'.format(service_name))
        os.exit(1)

    """ Get host IPV4 address
    """
    local_ipv4 = get_my_primary_local_ipv4()
    """ If host IP address from where the request came in matches
        the IP address of the requested service's host IP address,
        pick the endpoint
    """
    for i in range(len(services)):
        service = services[i]
        if service['ServiceAddress'] == local_ipv4:
            log.debug("picking address locally")
            endpoint = '{}:{}'.format(service['ServiceAddress'],
                                      service['ServicePort'])
            return endpoint

    """ If service is not available locally, picak a random
        endpoint for the service from the list
    """
    service = services[randint(0, len(services) - 1)]
    endpoint = '{}:{}'.format(service['ServiceAddress'],
                              service['ServicePort'])

    return endpoint


def get_healthy_instances(consul_endpoint, service_name=None,
                          number_of_expected_services=None):
    """
    Verify in consul if any service is healthy
    :param consul_endpoint: a <host>:<port> string
    :param service_name: name of service to check, optional
    :param number_of_expected_services number of services to check for, optional
    :return: true if healthy, false otherwise
    """

    def check_health(service):
        _, serv_health = consul.health.service(service, passing=True)
        return not serv_health == []

    consul = connect_to_consult(consul_endpoint)

    if service_name is not None:
        return check_health(service_name)

    services = get_all_services(consul_endpoint)

    items = services.keys()

    if number_of_expected_services is not None and \
                    len(items) != number_of_expected_services:
        return False

    for item in items:
        if not check_health(item):
            return False

    return True


if __name__ == '__main__':
    # print get_endpoint_from_consul('10.100.198.220:8500', 'kafka')
    # print get_healthy_instances('10.100.198.220:8500', 'voltha-health')
    # print get_healthy_instances('10.100.198.220:8500')
    get_all_instances_of_service('10.100.198.220:8500', 'voltha-grpc')
