from __future__ import division

from autotest_lib.client.common_lib.cros.cfm.metrics import (
        media_info_metrics_extractor)

MEDIA_TYPE = media_info_metrics_extractor.MediaType
DIRECTION = media_info_metrics_extractor.Direction

# Delta used to determine if floating point values are equal.
FLOATING_POINT_COMPARISON_DELTA = 0.00001


def _avg(l):
    """
    Returns the average of the list or 0 if the list is empty.
    """
    return sum(l)/len(l) if l else 0


def _get_number_of_incoming_active_video_streams(extractor):
    """
    Calculates the number of incoming video streams.

    @param extractor media_info_metrics_extractor.MediaInfoMetricsExtractor.

    @returns List with (timestamp, number of incoming video streams) tuples.
    """
    # Get metrics of a kind we know exists and count the nuber of values
    # for each data point.
    fps_metrics = extractor.get_media_metric(
            'fps', direction=DIRECTION.RECEIVER, media_type=MEDIA_TYPE.VIDEO)
    return [(x, [len(y)]) for x, y in fps_metrics]


ADAPTATION_CHANGES = 'adaptation_changes'
ADAPTATION_REASON = 'adaptation_reason'
AVG_ENCODE_MS = 'avg_encode_ms'
BROWSER_CPU_PERCENT_OF_TOTAL = 'browser_cpu_percent'
CPU_PERCENT_OF_TOTAL = 'cpu_percent'
FRAMERATE_CAPTURED = 'framerate_catured'
FRAMERATE_DECODED = 'framerate_decoded'
FRAMERATE_ENCODED = 'framerate_encoded'
FRAMERATE_TO_RENDERER = 'framerate_to_renderer'
FRAMERATE_NETWORK_RECEIVED = 'framerate_network_received'
GPU_PERCENT_OF_TOTAL = 'gpu_cpu_percent'
NUMBER_OF_ACTIVE_INCOMING_VIDEO_STREAMS = 'num_active_vid_in_streams'
PROCESS_JS_MEMORY_USED = 'process_js_memory_used'
RENDERER_CPU_PERCENT_OF_TOTAL = 'renderer_cpu_percent'
VIDEO_RECEIVED_FRAME_HEIGHT = 'video_received_frame_height'
VIDEO_RECEIVED_FRAME_WIDTH = 'video_received_frame_width'
VIDEO_SENT_FRAME_HEIGHT = 'video_sent_frame_height'
VIDEO_SENT_FRAME_WIDTH = 'video_sent_frame_width'
VIDEO_SENT_PACKETS = 'video_sent_packets'


# Mapping between metric names and how to extract the named metric using the
# MediaInfoMetricsExtractor.
METRIC_NAME_TO_EXTRACTOR_FUNC_DICT = {
    ADAPTATION_CHANGES:
        lambda x: x.get_media_metric('adaptationChanges',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
    ADAPTATION_REASON:
        lambda x: x.get_media_metric('adaptationReason',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
    AVG_ENCODE_MS:
        lambda x: x.get_media_metric('avgEncodeMs',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
    BROWSER_CPU_PERCENT_OF_TOTAL:
        lambda x: x.get_top_level_metric('browserProcessCpuUsage'),
    CPU_PERCENT_OF_TOTAL:
        lambda x: x.get_top_level_metric('systemcpuusage'),
    FRAMERATE_CAPTURED:
        lambda x: x.get_media_metric('fps',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
    FRAMERATE_DECODED:
        lambda x: x.get_media_metric('fpsdecoded',
                                     direction=DIRECTION.RECEIVER,
                                     media_type=MEDIA_TYPE.VIDEO,
                                     post_process_func=_avg),
    FRAMERATE_ENCODED:
       lambda x: x.get_media_metric('fpsnetwork',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
    FRAMERATE_NETWORK_RECEIVED:
        lambda x: x.get_media_metric('fpsnetwork',
                                     direction=DIRECTION.RECEIVER,
                                     media_type=MEDIA_TYPE.VIDEO),
    FRAMERATE_TO_RENDERER:
        lambda x: x.get_media_metric('fps',
                                     direction=DIRECTION.RECEIVER,
                                     media_type=MEDIA_TYPE.VIDEO,
                                     post_process_func=_avg),
    GPU_PERCENT_OF_TOTAL:
        lambda x: x.get_top_level_metric('gpuProcessCpuUsage'),
    NUMBER_OF_ACTIVE_INCOMING_VIDEO_STREAMS:
        _get_number_of_incoming_active_video_streams,
    PROCESS_JS_MEMORY_USED:
        lambda x: x.get_top_level_metric('processJsMemoryUsed'),
    RENDERER_CPU_PERCENT_OF_TOTAL:
        lambda x: x.get_top_level_metric('processcpuusage'),
    VIDEO_RECEIVED_FRAME_WIDTH:
        lambda x: x.get_media_metric('width',
                                     direction=DIRECTION.RECEIVER,
                                     media_type=MEDIA_TYPE.VIDEO,
                                     post_process_func=_avg),
    VIDEO_RECEIVED_FRAME_HEIGHT:
        lambda x: x.get_media_metric('height',
                                     direction=DIRECTION.RECEIVER,
                                     media_type=MEDIA_TYPE.VIDEO,
                                     post_process_func=_avg),
    VIDEO_SENT_FRAME_HEIGHT:
        lambda x: x.get_media_metric('height',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
    VIDEO_SENT_FRAME_WIDTH:
        lambda x: x.get_media_metric('width',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
    VIDEO_SENT_PACKETS:
        lambda x: x.get_media_metric('packetssent',
                                     direction=DIRECTION.SENDER,
                                     media_type=MEDIA_TYPE.VIDEO),
}

class MetricsCollector(object):
    """Collects metrics for a test run."""

    def __init__(self, data_point_collector):
        """
        Initializes.

        @param data_point_collector
        """
        self._data_point_collector = data_point_collector
        self._extractor = None

    def collect_snapshot(self):
        """
        Stores new merics since the last call.

        Metrics can then be retrieved by calling get_metric.
        """
        self._data_point_collector.collect_snapshot()
        data_points = self._data_point_collector.get_data_points()
        # Replace the extractor on each snapshot to always support
        # getting metrics
        self._extractor = (media_info_metrics_extractor
                           .MediaInfoMetricsExtractor(data_points))

    def get_metric(self, name):
        """
        Gets the metric with the specified name.

        @param name The name of the metric
        @returns a list with (timestamp, value_list) tuples
        """
        if self._extractor is None:
            raise RuntimeError(
                    'collect_snapshot() must be called at least once.')
        return METRIC_NAME_TO_EXTRACTOR_FUNC_DICT[name](
                self._extractor)


class DataPointCollector(object):
    """Collects data points."""

    def __init__(self, cfm_facade):
        """
        Initializes.

        @param cfm_facade The cfm facade to use for getting data points.
        """
        self._cfm_facade = cfm_facade
        self._data_points = []

    def collect_snapshot(self):
        """
        Collects any new datapoints since the last collection.
        """
        data_points = self._cfm_facade.get_media_info_data_points()
        last_timestamp = (self._data_points[-1]['timestamp']
                          if self._data_points else 0)
        for data_point in data_points:
            if (data_point['timestamp'] >
                    last_timestamp + FLOATING_POINT_COMPARISON_DELTA):
                self._data_points.append(data_point)

    def get_data_points(self):
        """
        Gets all collected data points.
        """
        return self._data_points
