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 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()[-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)
