import logging
import sys

import pytest
from texttable import Texttable

import utils
from utils import helpers
from utils import ssh
from utils.k8s_client import K8SCliActions


logger = logging.getLogger(__name__)


def test_hw2hw(hw_pair, k8s_v1_client, request, html_report):
    """
    Simplified Performance Test: HW to HW test via some specific interface
    1. Get the nodes list from the config, or get computes from K8S nodes list
    2. Connect to the nodes, install iperf, iperf3 there
    3. Start iperf, iperf3 at some specific interface
    4. Measure HW to HW nodes via some interface IP, 1 thread
    5. Measure HW to HW nodes via some interface IP, 1 thread, multiple threads
       (10 by default)
    6. Draw the table with all pairs and results
    """
    k8s_actions = K8SCliActions(k8s_v1_client)
    config = utils.get_configuration()
    node_ssh_key_path = config.get("node_ssh_key_path", "")
    node_ssh_username = config.get("node_ssh_username", "mcc-user")
    iperf_time = int(config.get('iperf_time', 60))
    threads = int(config.get('multiple_threads_number', 10))
    iperf_utility = config.get('multiple_threads_iperf_utility', 'iperf3')
    result_table = Texttable(max_width=120)
    network_cidr = config.get('network_cidr', '')
    cleanup_list = []

    if not node_ssh_key_path:
        pytest.skip("No private key for the MOSK K8S nodes is provided. "
                    "Please set the ssh key path in the config option "
                    "'node_ssh_key_path'.")

    if not network_cidr:
        # TODO: implement setting several comma-separated net ranges
        # TODO: take some default (storage or tenant) interface if not set
        pytest.skip("No network interface is provided. Please set the "
                    "network range in the config option 'network_cidr'.")

    # get K8S nodes' names and Internal IPs for the hw_pair list
    nodes_info = k8s_actions.get_nodes_info_by_names(hw_pair)
    # connect to the nodes and prepare iperf
    node_connect = ssh.SSHTransport(address=nodes_info[0]["address"],
                                    username=node_ssh_username,
                                    private_key=node_ssh_key_path)
    for node in nodes_info:
        iperf_ip = node_connect.get_node_ip_addresses_from_cidr(
            node['address'], network_cidr, user=node_ssh_username,
            private_key=node_ssh_key_path)
        node["iperf_ip"] = iperf_ip
        logger.info(
            f"Connecting to the node {node['name']}, IP {node['address']}")
        iperf = ssh.IperfAtNode(
            ip=node["address"], iperf_test_ip=iperf_ip,
            user=node_ssh_username,
            private_key=node_ssh_key_path)
        if iperf.install_iperf:
            cleanup_list.append(node["address"])

    # Prepare the result table and run iperf3
    table_rows = [[
        'Test Case', 'Node 1', 'Node 2', 'Network', 'Result'
    ]]
    # Do iperf3 measurement #1
    measurement1 = f"HW to HW via {network_cidr} interface, 1 thread; iperf3"
    logger.info("Doing '{}' measurement...".format(measurement1))
    command1 = "iperf3 -c {} -t {} -B {} | grep sender | tail -n 1".format(
            nodes_info[1]["iperf_ip"], iperf_time, nodes_info[0]["iperf_ip"])
    logger.info(f"Running the command: {command1}")
    result1 = node_connect.exec_command(command1)
    res1 = (b" ".join(result1.split()[-4:-2:])).decode('utf-8')
    logger.info("Result #1 is {}".format(res1))
    table_rows.append([measurement1,
                       "{}".format(nodes_info[0]["name"]),
                       "{}".format(nodes_info[1]["name"]),
                       "{}".format(network_cidr),
                       "{}".format(res1)])

    # Do iperf/iperf3 measurement #2
    measurement2 = (f"HW to HW via {network_cidr} interface, {threads} "
                    f"threads; {iperf_utility}")
    logger.info(f"Doing '{measurement2}' measurement...")
    if iperf_utility == "iperf3":
        command2 = '{} -c {} -P {} -t {} -B {} | grep sender | tail -n 1'\
            .format(iperf_utility, nodes_info[1]["iperf_ip"],
                    threads, iperf_time, nodes_info[0]["iperf_ip"])
        logger.info(f"Running the command: {command2}")
        result2 = node_connect.exec_command(command2)
        res2 = (b" ".join(result2.split()[-4:-2:])).decode('utf-8')
    else:
        iperf_utility = "iperf"
        command2 = '{} -c {} -P {} -t {} -B {} | tail -n 2 | grep SUM'.format(
            iperf_utility, nodes_info[1]["iperf_ip"], threads, iperf_time,
            nodes_info[0]["iperf_ip"])
        logger.info(f"Running the command: {command2}")
        result2 = node_connect.exec_command(command2)
        res2 = (b" ".join(result2.split()[-2::])).decode('utf-8')
    logger.info("Result #2 is {}".format(res2))
    table_rows.append([measurement2,
                       "{}".format(nodes_info[0]["name"]),
                       "{}".format(nodes_info[1]["name"]),
                       "{}".format(network_cidr),
                       "{}".format(res2)])

    # Draw the results table
    logger.info("Drawing the table with iperf results...")
    result_table.add_rows(table_rows)
    sys.stdout.write('\n{}\n'.format(result_table.draw()))

    # Send the results to CSV file at reports/ directory
    helpers.create_test_result_table_csv_file(
        table_rows, request.node.name)

    # Delete the iperf, iperf3 packages if they were installed
    for ip in cleanup_list:
        ssh.IperfAtNode.remove_iperf_packages(
            ip, node_ssh_username, node_ssh_key_path)
