# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import errno
import hashlib
import logging
import math
import mmap
import os
import re

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import file_utils
from autotest_lib.client.cros import chrome_binary_test
from autotest_lib.client.cros.video import device_capability
from autotest_lib.client.cros.video import encoder_utils
from autotest_lib.client.cros.video import helper_logger


DOWNLOAD_BASE = ('http://commondatastorage.googleapis.com'
                 '/chromiumos-test-assets-public/')

VEA_BINARY = 'video_encode_accelerator_unittest'
TIME_BINARY = '/usr/local/bin/time'

# The format used for 'time': <real time> <kernel time> <user time>
TIME_OUTPUT_FORMAT = '%e %S %U'

FRAME_STATS_SUFFIX = 'frame-data.csv'
TEST_LOG_SUFFIX = 'test.log'
TIME_LOG_SUFFIX = 'time.log'

# Performance keys:
# FPS (i.e. encoder throughput)
KEY_FPS = 'fps'
# Encode latencies at the 50th, 75th, and 95th percentiles.
# Encode latency is the delay from input of a frame to output of the encoded
# bitstream.
KEY_ENCODE_LATENCY_50 = 'encode_latency.50_percentile'
KEY_ENCODE_LATENCY_75 = 'encode_latency.75_percentile'
KEY_ENCODE_LATENCY_95 = 'encode_latency.95_percentile'
# CPU usage in kernel space
KEY_CPU_KERNEL_USAGE = 'cpu_usage.kernel'
# CPU usage in user space
KEY_CPU_USER_USAGE = 'cpu_usage.user'

# Units of performance values:
UNIT_MILLISECOND = 'milliseconds'
UNIT_MICROSECOND = 'us'
UNIT_RATIO = 'ratio'
UNIT_FPS = 'fps'

RE_FPS = re.compile(r'^Measured encoder FPS: ([+\-]?[0-9.]+)$', re.MULTILINE)
RE_ENCODE_LATENCY_50 = re.compile(
    r'^Encode latency for the 50th percentile: (\d+) us$',
    re.MULTILINE)
RE_ENCODE_LATENCY_75 = re.compile(
    r'^Encode latency for the 75th percentile: (\d+) us$',
    re.MULTILINE)
RE_ENCODE_LATENCY_95 = re.compile(
    r'^Encode latency for the 95th percentile: (\d+) us$',
    re.MULTILINE)


def _remove_if_exists(filepath):
    try:
        os.remove(filepath)
    except OSError, e:
        if e.errno != errno.ENOENT:  # no such file
            raise


class video_VEAPerf(chrome_binary_test.ChromeBinaryTest):
    """
    This test monitors several performance metrics reported by Chrome test
    binary, video_encode_accelerator_unittest.
    """

    version = 1

    def _logperf(self, test_name, key, value, units, higher_is_better=False):
        description = '%s.%s' % (test_name, key)
        self.output_perf_value(
                description=description, value=value, units=units,
                higher_is_better=higher_is_better)


    def _analyze_fps(self, test_name, log_file):
        """
        Analyzes FPS info from result log file.
        """
        with open(log_file, 'r') as f:
            mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
            fps = [float(m.group(1)) for m in RE_FPS.finditer(mm)]
            mm.close()
        if len(fps) != 1:
            raise error.TestError('Parsing FPS failed w/ %d occurrence(s).' %
                                  len(fps))
        self._logperf(test_name, KEY_FPS, fps[0], UNIT_FPS, True)


    def _analyze_encode_latency(self, test_name, log_file):
        """
        Analyzes encode latency from result log file.
        """
        with open(log_file, 'r') as f:
            mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
            latency_50 = [int(m.group(1)) for m in
                          RE_ENCODE_LATENCY_50.finditer(mm)]
            latency_75 = [int(m.group(1)) for m in
                          RE_ENCODE_LATENCY_75.finditer(mm)]
            latency_95 = [int(m.group(1)) for m in
                          RE_ENCODE_LATENCY_95.finditer(mm)]
            mm.close()
        if any([len(l) != 1 for l in [latency_50, latency_75, latency_95]]):
            raise error.TestError('Parsing encode latency failed.')
        self._logperf(test_name, KEY_ENCODE_LATENCY_50, latency_50[0],
                      UNIT_MICROSECOND)
        self._logperf(test_name, KEY_ENCODE_LATENCY_75, latency_75[0],
                      UNIT_MICROSECOND)
        self._logperf(test_name, KEY_ENCODE_LATENCY_95, latency_95[0],
                      UNIT_MICROSECOND)


    def _analyze_cpu_usage(self, test_name, time_log_file):
        """
        Analyzes CPU usage from the output of 'time' command.
        """
        with open(time_log_file) as f:
            content = f.read()
        r, s, u = (float(x) for x in content.split())
        self._logperf(test_name, KEY_CPU_USER_USAGE, u / r, UNIT_RATIO)
        self._logperf(test_name, KEY_CPU_KERNEL_USAGE, s / r, UNIT_RATIO)


    def _analyze_frame_stats(self, test_name, frame_stats_file):
        """
        Analyzes quality from --frame_stats output CSV. Assumes YUV420 (for MSE
        samples per channel).
        """
        def mse_to_psnr(samples, peak, mse):
            """
            Generate PSNR from MSE for a frame.
            """
            MAX_PSNR = 100.0
            # Prevent a divide-by-zero, MSE at 0 is perfect quality (no error).
            if mse == 0:
                return MAX_PSNR
            psnr = 10.0 * math.log10(peak * peak * samples / float(mse))
            return min(psnr, MAX_PSNR)

        frame_ssim = {'y': [], 'u': [], 'v': [], 'combined': []}
        frame_psnr = {'y': [], 'u': [], 'v': [], 'combined': []}
        for line in open(frame_stats_file):
            (frame, width, height,
                ssim_y, ssim_u, ssim_v, mse_y, mse_u, mse_v) = line.split(',')
            # Skip CSV header.
            if frame == 'frame':
                continue
            frame = int(frame)
            width = int(width)
            height = int(height)
            ssim_y = float(ssim_y)
            ssim_u = float(ssim_u)
            ssim_v = float(ssim_v)
            mse_y = int(mse_y)
            mse_u = int(mse_u)
            mse_v = int(mse_v)

            frame_ssim['y'].append(ssim_y)
            frame_ssim['u'].append(ssim_u)
            frame_ssim['v'].append(ssim_v)
            # Weighting of YUV channels for SSIM taken from libvpx.
            frame_ssim['combined'].append(
                0.8 * ssim_y + 0.1 * (ssim_u + ssim_v))

            # Samples per MSE score assumes YUV420 subsampling.
            frame_psnr['y'].append(
                mse_to_psnr(width * height * 4 / 4, 255, mse_y))
            frame_psnr['u'].append(
                mse_to_psnr(width * height * 1 / 4, 255, mse_u))
            frame_psnr['v'].append(
                mse_to_psnr(width * height * 1 / 4, 255, mse_v))
            frame_psnr['combined'].append(
                mse_to_psnr(
                    width * height * 6 / 4, 255, mse_y + mse_u + mse_v))

        for channel in ['y', 'u', 'v', 'combined']:
            # Log stats with a key similar to 'quality.ssim.y.max'. For combined
            # stats the channel is omitted ('quality.ssim.max').
            key = 'quality.%s'
            if channel is not 'combined':
                key += '.' + channel
            key += '.%s'
            for (stat, func) in [('min', min), ('max', max),
                                 ('avg', lambda x: sum(x) / len(x))]:
                self._logperf(test_name, key % ('ssim', stat),
                              func(frame_ssim[channel]), None,
                              higher_is_better=True)
                self._logperf(test_name, key % ('psnr', stat),
                              func(frame_psnr[channel]), None,
                              higher_is_better=True)


    def _get_profile_name(self, profile):
        """
        Gets profile name from a profile index.
        """
        if profile == 1:
            return 'h264'
        elif profile == 11:
            return 'vp8'
        else:
            raise error.TestError('Internal error.')


    def _convert_test_name(self, path, on_cloud, profile):
        """Converts source path to test name and output video file name.

        For example: for the path on cloud
            "tulip2/tulip2-1280x720-1b95123232922fe0067869c74e19cd09.yuv"

        We will derive the test case's name as "tulip2-1280x720.vp8" or
        "tulip2-1280x720.h264" depending on the profile. The MD5 checksum in
        path will be stripped.

        For the local file, we use the base name directly.

        @param path: The local path or download path.
        @param on_cloud: Whether the file is on cloud.
        @param profile: Profile index.

        @returns a pair of (test name, output video file name)
        """
        s = os.path.basename(path)
        name = s[:s.rfind('-' if on_cloud else '.')]
        profile_name = self._get_profile_name(profile)
        return (name + '_' + profile_name, name + '.' + profile_name)


    def _download_video(self, path_on_cloud, local_file):
        url = '%s%s' % (DOWNLOAD_BASE, path_on_cloud)
        logging.info('download "%s" to "%s"', url, local_file)

        file_utils.download_file(url, local_file)

        with open(local_file, 'r') as r:
            md5sum = hashlib.md5(r.read()).hexdigest()
            if md5sum not in path_on_cloud:
                raise error.TestError('unmatched md5 sum: %s' % md5sum)


    def _get_result_filename(self, test_name, subtype, suffix):
        return os.path.join(self.resultsdir,
                            '%s_%s_%s' % (test_name, subtype, suffix))


    def _get_vea_unittest_args(self, test_stream_data, test_log_file):
        vea_args = [
            '--test_stream_data=%s' % test_stream_data,
            '--output_log="%s"' % test_log_file,
            '--ozone-platform=gbm',
            helper_logger.chrome_vmodule_flag()]
        if encoder_utils.has_broken_flush():
            vea_args.append('--disable_flush')
        return vea_args


    def _run_test_case(self, test_name, test_stream_data):
        """
        Runs a VEA unit test.

        @param test_name: Name of this test case.
        @param test_stream_data: Parameter to --test_stream_data in vea_unittest.
        """
        # Get FPS.
        test_log_file = self._get_result_filename(test_name, 'fullspeed',
                                                  TEST_LOG_SUFFIX)
        vea_args = self._get_vea_unittest_args(test_stream_data, test_log_file)
        vea_args += ['--gtest_filter=EncoderPerf/*/0']
        self.run_chrome_test_binary(VEA_BINARY, ' '.join(vea_args))
        self._analyze_fps(test_name, test_log_file)

        # Get CPU usage and encode latency under specified frame rate.
        test_log_file = self._get_result_filename(test_name, 'fixedspeed',
                                                  TEST_LOG_SUFFIX)
        time_log_file = self._get_result_filename(test_name, 'fixedspeed',
                                                  TIME_LOG_SUFFIX)
        vea_args = self._get_vea_unittest_args(test_stream_data, test_log_file)
        vea_args += ['--gtest_filter=SimpleEncode/*/0',
                     '--run_at_fps',
                     '--measure_latency']
        time_cmd = ('%s -f "%s" -o "%s" ' %
                    (TIME_BINARY, TIME_OUTPUT_FORMAT, time_log_file))
        self.run_chrome_test_binary(VEA_BINARY, ' '.join(vea_args),
                                    prefix=time_cmd)
        self._analyze_encode_latency(test_name, test_log_file)
        self._analyze_cpu_usage(test_name, time_log_file)

        # TODO(pbos): Measure quality at more bitrates.
        # Generate SSIM/PSNR scores (objective quality metrics).
        test_log_file = self._get_result_filename(test_name, 'quality',
                                                  TEST_LOG_SUFFIX)
        frame_stats_file = self._get_result_filename(test_name, 'quality',
                                                    FRAME_STATS_SUFFIX)
        vea_args = self._get_vea_unittest_args(test_stream_data, test_log_file)
        vea_args += ['--gtest_filter=SimpleEncode/*/0',
                     '--frame_stats="%s"' % frame_stats_file]
        self.run_chrome_test_binary(VEA_BINARY, ' '.join(vea_args))
        self._analyze_frame_stats(test_name, frame_stats_file)


    @helper_logger.video_log_wrapper
    @chrome_binary_test.nuke_chrome
    def run_once(self, test_cases, required_cap):
        """
        Tests ChromeOS video hardware encoder performance.
        """
        last_error = None
        device_capability.DeviceCapability().ensure_capability(required_cap)
        for (path, on_cloud, width, height, requested_bit_rate,
             profile, requested_frame_rate) in test_cases:
            try:
                test_name, output_name = self._convert_test_name(
                    path, on_cloud, profile)
                if on_cloud:
                    input_path = os.path.join(self.tmpdir,
                                              os.path.basename(path))
                    self._download_video(path, input_path)
                else:
                    input_path = os.path.join(self.cr_source_dir, path)
                output_path = os.path.join(self.tmpdir, output_name)
                test_stream_data = '%s:%s:%s:%s:%s:%s:%s' % (
                    input_path, width, height, profile, output_path,
                    requested_bit_rate, requested_frame_rate)
                self._run_test_case(test_name, test_stream_data)
            except Exception as last_error:
                # Log the error and continue to the next test case.
                logging.exception(last_error)
            finally:
                if on_cloud:
                    _remove_if_exists(input_path)
                _remove_if_exists(output_path)

        if last_error:
            raise last_error
