# Copyright (c) 2017-2018 VMware, Inc.  All rights reserved.
# -- VMware Confidential

"""VCDB VMODL In-Place (B2B) Upgrade Utilities

This module contains functions that are not direct functional necessity,
however they help with diagnosing various non-functional problems.
"""

import io
import pstats
import subprocess


def GetDiskUsage(partitions):
    """We need to provide the Disk Requirements for the upgrade in MB

    @param[in] Paritions  A list {"/path/to/part1", "/path/to/part2", ...}

    This function parses the result of 'df -m'. There might be a better way.
    """

    result = {}

    for p in partitions:
        output = subprocess.check_output(["df", "-m", p])

        # Kills extra spaces and decodes the "bytes" data.
        l = " ".join(output.decode("utf8").splitlines()[-1].split())

        # This is the Used space in the partition, in MB.
        result[p] = int(l.split()[2])

    return result


def LogDiskUsage(logger):
    """The Disk Usage will help to diagnose spacing problems.

    This function provides size measuring capabilities to this particular
    part of the In-Place Upgrade. Any failure to log the disk usage is _not_
    fatal for the Upgrade.
    """

    command = ["df", "-m"]
    logger.info("Checking disk usage with command: %s", command)

    # pylint: disable=broad-except
    try:
        output = subprocess.check_output(command)
        for l in output.decode("utf-8").rstrip().splitlines():
            logger.info(l)
    except subprocess.CalledProcessError as e:
        logger.warning("Disk usage check failed, non-fatal failure: %s", e)
    except OSError as e:
        logger.warning("OS Error happened during 'df' invocation, "
                       "non-fatal failure: %s", e)
    except Exception as e:
        logger.warning("Unknown error happened during 'df' invocation: %s", e)


def LogProfile(logger, prof):
    """The profile log will help to diagnose bottlenecks.

    Having the slowest 10 cumulative functions at the top is a good start.
    """

    logStr = io.StringIO()
    ps = pstats.Stats(prof, stream=logStr).sort_stats("cumulative")
    ps.print_stats(100)

    for l in logStr.getvalue().splitlines():
        logger.info(l)
