# ================================================================================
# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
# ================================================================================
# 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.
# ============LICENSE_END=========================================================
#
# ECOMP is a trademark and service mark of AT&T Intellectual Property.

"""client to talk to consul at the standard port 8500"""

import base64
import json
import logging

import requests

from .customize import CustomizerUser

class DiscoveryClient(object):
    """talking to consul at http://consul:8500

    relies on proper --add-host "consul:<consul-agent ip>" in
    docker run command that runs along the consul-agent:

    docker run --name ${APPNAME} -d
        -e HOSTNAME
        --add-host "consul:<consul-agent ip>"
        -v ${BASEDIR}/logs:${TARGETDIR}/logs
        -v ${BASEDIR}/etc:${TARGETDIR}/etc
        -p <outport>:<innerport>
        ${APPNAME}:latest
    """
    CONSUL_SERVICE_MASK = "http://consul:8500/v1/catalog/service/{0}"
    CONSUL_KV_MASK = "http://consul:8500/v1/kv/{0}"
    _logger = logging.getLogger("policy_handler.discovery")

    @staticmethod
    def get_service_url(audit, service_name):
        """find the service record in consul"""
        service_path = DiscoveryClient.CONSUL_SERVICE_MASK.format(service_name)
        log_line = "discover {0}".format(service_path)
        DiscoveryClient._logger.info(log_line)
        audit.info(log_line)
        response = requests.get(service_path)

        log_line = "response {0} for {1}: {2}".format(
            response.status_code, service_path, response.text)
        DiscoveryClient._logger.info(log_line)
        audit.info(log_line)

        response.raise_for_status()

        service = response.json()
        if not service:
            log_line = "failed discover {0}".format(service_path)
            DiscoveryClient._logger.error(log_line)
            audit.error(log_line)
            return
        service = service[0]

        service_url = CustomizerUser.get_customizer().get_service_url(audit, service_name, service)
        if not service_url:
            log_line = "failed to get service_url for {0}".format(service_name)
            DiscoveryClient._logger.error(log_line)
            audit.error(log_line)
            return

        log_line = "got service_url: {0} for {1}".format(service_url, service_name)
        DiscoveryClient._logger.info(log_line)
        audit.info(log_line)
        return service_url

    @staticmethod
    def get_value(key):
        """get the value for the key from consul-kv"""
        response = requests.get(DiscoveryClient.CONSUL_KV_MASK.format(key))
        response.raise_for_status()
        data = response.json()
        if not data:
            DiscoveryClient._logger.error("failed get_value %s", key)
            return
        value = base64.b64decode(data[0]["Value"]).decode("utf-8")
        DiscoveryClient._logger.info("consul-kv key=%s value(%s) data=%s",
                                     key, value, json.dumps(data))
        return json.loads(value)
