# (c) Copyright IBM Corp. 2021
# (c) Copyright Instana Inc. 2018

import os
import pytest

testenv = {}

"""
Cassandra Environment
"""
testenv['cassandra_host'] = os.environ.get('CASSANDRA_HOST', '127.0.0.1')
testenv['cassandra_username'] = os.environ.get('CASSANDRA_USERNAME', 'Administrator')
testenv['cassandra_password'] = os.environ.get('CASSANDRA_PASSWORD', 'password')

"""
CouchDB Environment
"""
testenv['couchdb_host'] = os.environ.get('COUCHDB_HOST', '127.0.0.1')
testenv['couchdb_username'] = os.environ.get('COUCHDB_USERNAME', 'Administrator')
testenv['couchdb_password'] = os.environ.get('COUCHDB_PASSWORD', 'password')

"""
MySQL Environment
"""
if 'MYSQL_HOST' in os.environ:
    testenv['mysql_host'] = os.environ['MYSQL_HOST']
else:
    testenv['mysql_host'] = '127.0.0.1'

testenv['mysql_port'] = int(os.environ.get('MYSQL_PORT', '3306'))
testenv['mysql_db'] = os.environ.get('MYSQL_DATABASE', 'instana_test_db')
testenv['mysql_user'] = os.environ.get('MYSQL_USER', 'root')
testenv['mysql_pw'] = os.environ.get('MYSQL_ROOT_PASSWORD', 'passw0rd')

"""
PostgreSQL Environment
"""
testenv['postgresql_host'] = os.environ.get('POSTGRES_HOST', '127.0.0.1')
testenv['postgresql_port'] = int(os.environ.get('POSTGRES_PORT', '5432'))
testenv['postgresql_db'] = os.environ.get('POSTGRES_DB', 'instana_test_db')
testenv['postgresql_user'] = os.environ.get('POSTGRES_USER', 'root')
testenv['postgresql_pw'] = os.environ.get('POSTGRES_PW', 'passw0rd')

"""
Redis Environment
"""
testenv['redis_host'] = os.environ.get('REDIS_HOST', '127.0.0.1')

"""
MongoDB Environment
"""
testenv['mongodb_host'] = os.environ.get('MONGO_HOST', '127.0.0.1')
testenv['mongodb_port'] = os.environ.get('MONGO_PORT', '27017')
testenv['mongodb_user'] = os.environ.get('MONGO_USER', None)
testenv['mongodb_pw'] = os.environ.get('MONGO_PW', None)


def drop_log_spans_from_list(spans):
    """
    Log spans may occur randomly in test runs because of various intentional errors (for testing). This
    helper method will remove all of the log spans from <spans> and return the remaining list.  Helpful
    for those tests where we are not testing log spans - where log spans are just noise.
    @param spans: the list of spans to filter
    @return: a filtered list of spans
    """
    new_list = []
    for span in spans:
        if span.n != 'log':
            new_list.append(span)
    return new_list


def fail_with_message_and_span_dump(msg, spans):
    """
    Helper method to fail a test when the number of spans isn't what was expected.  This helper
    will print <msg> and dump the list of spans in <spans>.

    @param msg: Descriptive message to print with the failure
    @param spans: the list of spans to dump
    @return: None
    """
    span_count = len(spans)
    span_dump = "\nDumping all collected spans (%d) -->\n" % span_count
    if span_count > 0:
        for span in spans:
            span.stack = '<snipped>'
            span_dump += repr(span) + '\n'
    pytest.fail(msg + span_dump, True)


def get_first_span_by_name(spans, name):
    """
    Get the first span in <spans> that has a span.n value of <name>
    @param spans: the list of spans to search
    @param name: the name to search for
    @return: Span or None if nothing found
    """
    for span in spans:
        if span.n == name:
            return span
    return None


def get_first_span_by_filter(spans, filter):
    """
    Get the first span in <spans> that matches <filter>

    Example:
    filter = lambda span: span.n == "tornado-server" and span.data["http"]["status"] == 301
    tornado_301_span = get_first_span_by_filter(spans, filter)

    @param spans: the list of spans to search
    @param filter: the filter to search by
    @return: Span or None if nothing matched
    """
    for span in spans:
        if filter(span) is True:
            return span
    return None


def get_spans_by_filter(spans, filter):
    """
    Get all spans in <spans> that matches <filter>

    Example:
    filter = lambda span: span.n == "tornado-server" and span.data["http"]["status"] == 301
    tornado_301_spans = get_spans_by_filter(spans, filter)

    @param spans: the list of spans to search
    @param filter: the filter to search by
    @return: list of spans
    """
    results = []
    for span in spans:
        if filter(span) is True:
            results.append(span)
    return results


def launch_traced_request(url):
    import requests
    from instana.log import logger
    from instana.singletons import tracer

    logger.warn("Launching request with a root SDK span name of 'launch_traced_request'")

    with tracer.start_active_span('launch_traced_request'):
        response = requests.get(url)

    return response
