# 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 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()]
        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
