from __future__ import print_function
from builtins import str
import os
import pytest
import atexit
import utils
import logging

logging.basicConfig(
    filename="{dir}/full.log".format(
        dir=os.environ.get("PYTEST_REPORT_DIR") if os.environ.get("PYTEST_REPORT_DIR") else '.'
    ),
    level=logging.DEBUG,
    format='[%(asctime)-15s] [%(funcName)s:%(lineno)s]  %(message)s'
)


@pytest.fixture(autouse=True)
def add_testname_to_saltapi_logs(request):
    logging.info("\n{sep}\n {testname} \n{sep}\n".format(
        sep="*"*100,
        testname=request.node.name
    ))


@pytest.fixture(scope='session')
def local_salt_client():
    pytest.local_salt_client = utils.init_salt_client()
    return pytest.local_salt_client


nodes = utils.calculate_groups()


@pytest.fixture(scope='session', params=list(nodes.items()), ids=list(nodes.keys()))
def nodes_in_group(request):
    return request.param


@pytest.fixture(scope='session')
def ctl_nodes_pillar(local_salt_client):
    '''Return controller node pillars (OS or k8s ctls).
       This will help to identify nodes to use for UI curl tests.
       If no platform is installed (no OS or k8s) we need to skip
       the test (product team use case).
    '''
    salt_output = local_salt_client.test_ping(tgt='keystone:server')
    if salt_output:
        return "keystone:server"
    else:
        salt_output = local_salt_client.test_ping(tgt='etcd:server')
        return "etcd:server" if salt_output else pytest.skip("Neither \
            Openstack nor k8s is found. Skipping test")


@pytest.fixture(scope='session')
def check_openstack(local_salt_client):
    salt_output = local_salt_client.test_ping(tgt='keystone:server')
    if not salt_output:
        pytest.skip("Openstack not found or keystone:server pillar \
          are not found on this environment.")


@pytest.fixture(scope='session')
def check_ironic(local_salt_client):
    salt_output = local_salt_client.test_ping(tgt='ironic:client')
    if not salt_output:
        pytest.skip("Ironic service is not found or ironic:client pillar is "
                    "not found on this environment.")


@pytest.fixture(scope='session')
def check_drivetrain(local_salt_client):
    salt_output = local_salt_client.test_ping(tgt='I@jenkins:client and not I@salt:master',
                                              expr_form='compound')
    if not salt_output:
        pytest.skip("Drivetrain service or jenkins:client pillar \
          are not found on this environment.")


@pytest.fixture(scope='session')
def check_prometheus(local_salt_client):
    salt_output = local_salt_client.test_ping(tgt='prometheus:server')
    if not salt_output:
        pytest.skip("Prometheus service or prometheus:server pillar \
          are not found on this environment.")


@pytest.fixture(scope='session')
def check_alerta(local_salt_client):
    salt_output = local_salt_client.test_ping(tgt='prometheus:alerta')
    if not salt_output:
        pytest.skip("Alerta service or prometheus:alerta pillar \
              are not found on this environment.")


@pytest.fixture(scope='session')
def check_kibana(local_salt_client):
    salt_output = local_salt_client.test_ping(tgt='kibana:server')
    if not salt_output:
        pytest.skip("Kibana service or kibana:server pillar \
          are not found on this environment.")


@pytest.fixture(scope='session')
def check_grafana(local_salt_client):
    salt_output = local_salt_client.test_ping(tgt='grafana:client')
    if not salt_output:
        pytest.skip("Grafana service or grafana:client pillar \
          are not found on this environment.")


@pytest.fixture(scope='session')
def check_cinder_backends(local_salt_client):
    backends_cinder_available = local_salt_client.test_ping(tgt='cinder:controller')
    if not backends_cinder_available or not any(backends_cinder_available.values()):
        pytest.skip("Cinder service or cinder:controller:backend pillar \
        are not found on this environment.")


def pytest_namespace():
    return {'contrail': None}


@pytest.fixture(scope='module')
def contrail(local_salt_client):
    probe = local_salt_client.cmd(
        tgt='opencontrail:control',
        fun='pillar.get',
        param='opencontrail:control:version',
        expr_form='pillar')
    if not probe:
        pytest.skip("Contrail is not found on this environment")
    versions = set(probe.values())
    if len(versions) != 1:
        pytest.fail('Contrail versions are not the same: {}'.format(probe))
    pytest.contrail = str(versions.pop())[:1]


@pytest.fixture(scope='session')
def check_kdt(local_salt_client):
    kdt_nodes_available = local_salt_client.test_ping(
        tgt="I@gerrit:client and I@kubernetes:pool and not I@salt:master",
        expr_form='compound'
    )
    if not kdt_nodes_available:
        pytest.skip("No 'kdt' nodes found. Skipping this test...")
    return list(kdt_nodes_available.keys())


@pytest.fixture(scope='session')
def check_kfg(local_salt_client):
    kfg_nodes_available = local_salt_client.cmd(
        tgt="I@kubernetes:pool and I@salt:master",
        expr_form='compound'
    )
    if not kfg_nodes_available:
        pytest.skip("No cfg-under-Kubernetes nodes found. Skipping this test...")
    return list(kfg_nodes_available.keys())


@pytest.fixture(scope='session')
def check_cicd(local_salt_client):
    cicd_nodes_available = local_salt_client.test_ping(
        tgt="I@gerrit:client and I@docker:swarm",
        expr_form='compound'
    )
    if not cicd_nodes_available:
        pytest.skip("No 'cid' nodes found. Skipping this test...")


@pytest.fixture(autouse=True, scope='session')
def print_node_version(local_salt_client):
    """
        Gets info about each node using salt command, info is represented as a dictionary with :
        {node_name1: output1, node_name2: ...}

        :print to output the table with results after completing all tests if nodes and salt output exist.
                Prints nothing otherwise
        :return None
    """
    try:
        filename_with_versions = "/etc/image_version"
        cat_image_version_file = "if [ -f '{name}' ]; then \
                                        cat {name}; \
                                    else \
                                        echo BUILD_TIMESTAMP='no {name}'; \
                                        echo BUILD_TIMESTAMP_RFC='no {name}'; \
                                    fi ".format(name=filename_with_versions)

        list_version = local_salt_client.cmd(
            tgt='*',
            param='echo "NODE_INFO=$(uname -sr)" && ' + cat_image_version_file,
            expr_form='compound')
        if list_version.__len__() == 0:
            yield
        parsed = {k: v.split('\n') for k, v in list(list_version.items())}
        columns = [name.split('=')[0] for name in list(parsed.values())[0]]

        template = "{:<40} | {:<25} | {:<25} | {:<25}\n"

        report_text = template.format("NODE", *columns)
        for node, data in sorted(parsed.items()):
            report_text += template.format(node, *[item.split("=")[1] for item in data])

        def write_report():
            # DO NOT change to logging
            print(report_text)
        atexit.register(write_report)
        yield
    except Exception as e:
        logging.info("print_node_version:: some error occurred: {}".format(e))
        yield
