import logging
import pytest
import random
import subprocess
import sys
import time

import utils
from utils import helpers

from texttable import Texttable

logger = logging.getLogger(__name__)


def is_parsable(value, to):
    """
    Check if value can be converted into some type
    :param value:  input value that should be converted
    :param to: type of output value like int, float. It's not a string!
    :return: bool
    """
    try:
        to(value)
    except BaseException:
        return False
    return True


@pytest.fixture
def create_image():
    image_size_megabytes = utils.get_configuration().get("IMAGE_SIZE_MB", 9000)
    create_file_cmdline = 'dd if=/dev/zero of=/tmp/image_mk_framework.dd ' \
                          'bs=1M count={} 2>/dev/null' \
                          ''.format(image_size_megabytes)
    is_cmd_successful = subprocess.call(create_file_cmdline, shell=True) == 0
    logger.info("Created local image file /tmp/image_mk_framework.dd")
    yield is_cmd_successful

    # teardown
    logger.info("Deleting /tmp/image_mk_framework.dd file")
    subprocess.call('rm -f /tmp/image_mk_framework.dd', shell=True)
    subprocess.call('rm -f /tmp/image_mk_framework.download', shell=True)


def test_speed_glance(create_image, openstack_clients,
                      request, html_report):
    """
    Simplified Performance Tests Download / upload Glance
    1. Create file with random data (dd)
    2. Upload data as image to glance.
    3. Download image.
    4. Measure download/upload speed and print them into stdout
    """
    result_table = Texttable(max_width=120)
    table_rows = [["Test Speed Glance", "Image Size", "Time Consumed",
                   "Result"]]
    image_size_megabytes = utils.get_configuration().get("IMAGE_SIZE_MB")
    if not is_parsable(image_size_megabytes, int):
        pytest.fail("Can't convert IMAGE_SIZE_MB={} to 'int'".format(
            image_size_megabytes))
    image_size_megabytes = int(image_size_megabytes)
    if not create_image:
        pytest.skip("Can't create image, maybe there is lack of disk "
                    "space to create file {}MB".
                    format(image_size_megabytes))
    image_name = "spt-test-image-{}".format(random.randrange(100, 999))
    try:
        image = openstack_clients.image.images.create(
            name=image_name,
            disk_format='raw',
            container_format='bare')
        logger.info("Created an image {} in Glance.".format(image_name))
    except BaseException as e:
        logger.info("Could not create image in Glance. See details: {}"
                    "".format(e))
        pytest.fail("Can't create image in Glance. Occurred error: {}"
                    "".format(e))

    logger.info("Testing upload file speed...")
    start_time = time.time()
    try:
        openstack_clients.image.images.upload(
            image.id, image_data=open("/tmp/image_mk_framework.dd", 'rb'))
    except BaseException as e:
        pytest.fail("Can't upload image in Glance. "
                    "Occurred error: {}".format(e))
    end_time = time.time()

    time_diff = end_time - start_time
    speed_upload = image_size_megabytes / time_diff
    table_rows.append(["Upload",
                       "{} MB".format(image_size_megabytes),
                       "{} s".format(round(time_diff, 3)),
                       "{} MB/s".format(round(speed_upload, 2))])

    logger.info("Testing download file speed...")
    start_time = time.time()
    with open("/tmp/image_mk_framework.download", 'wb') as image_file:
        for item in openstack_clients.image.images.data(image.id):
            image_file.write(item)
    end_time = time.time()

    time_diff = end_time - start_time
    speed_download = image_size_megabytes / time_diff
    table_rows.append(["Download",
                       "{} MB".format(image_size_megabytes),
                       "{} s".format(round(time_diff, 3)),
                       "{} MB/s".format(round(speed_download, 2))])
    logger.info("Deleted image {}.".format(image.id))
    openstack_clients.image.images.delete(image.id)

    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)
