# Copyright 2017 The Chromium OS 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 logging
import os
import time

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.graphics import graphics_utils
from autotest_lib.client.cros.image_comparison import pdiff_image_comparer

def get_percent_difference(file1, file2):
    """
    Performs pixel comparison of two files, given by their paths |file1|
    and |file2| using terminal tool 'perceptualdiff' and returns percentage
    difference of the total file size.

    @param file1: path to image
    @param file2: path to secondary image
    @return: percentage difference of total file size.
    @raise ValueError: if image dimensions are not the same
    @raise OSError: if file does not exist or cannot be opened.

    """
    # Using pdiff image comparer to compare the two images. This class
    # invokes the terminal tool perceptualdiff.
    pdi = pdiff_image_comparer.PdiffImageComparer()
    diff_bytes = pdi.compare(file1, file2)[0]
    return round(100. * diff_bytes / os.path.getsize(file1))


class platform_TabletMode(test.test):
    """
    Verify that tablet mode toggles appropriately.
    """
    version = 1
    _WAIT = 5
    _SHORT_WAIT = 1
    SPOOF_CMD = 'ectool motionsense spoof '
    # Disable spoof mode and return into laptop state.
    RESET_SENSOR_0 = '-- 0 0'
    RESET_SENSOR_1 = '-- 1 0'
    # Spoof sensor 1 to force laptop into landscape tablet mode.
    LANDSCAPE_SENSOR_1 = '-- 1 1 32 -16256 -224'
    # Spoof sensor 0 and sensor 1 to force laptop into portrait tablet mode.
    PORTRAIT_SENSOR_0 = '-- 0 1 -7760 -864 -14112'
    PORTRAIT_SENSOR_1 = '-- 1 1 -7936 848 14480'
    ERRORS = []

    def _revert_laptop(self):
        """Resets sensors to revert back to laptop mode."""
        utils.system(self.SPOOF_CMD + self.RESET_SENSOR_0)
        time.sleep(self._SHORT_WAIT)
        utils.system(self.SPOOF_CMD + self.RESET_SENSOR_1)
        time.sleep(self._WAIT)

    def _spoof_tablet_landscape(self):
        """Spoofs sensors to change into tablet landscape mode."""
        utils.system(self.SPOOF_CMD + self.LANDSCAPE_SENSOR_1)
        time.sleep(self._WAIT)

    def _spoof_tablet_portrait(self):
        """Spoofs sensors to change into tablet portrait mode."""
        utils.system(self.SPOOF_CMD + self.PORTRAIT_SENSOR_0)
        time.sleep(self._SHORT_WAIT)
        utils.system(self.SPOOF_CMD + self.PORTRAIT_SENSOR_1)
        time.sleep(self._WAIT)

    def _take_screenshot(self, suffix):
        """
        Captures a screenshot of the current VT screen in PNG format.

        @param suffixcurrent_vt: desired vt for screenshot.

        @returns the path of the screenshot file.

        """
        return graphics_utils.take_screenshot(self.resultsdir,
                                              suffix + '_tablet_mode')

    def _verify_difference(self, screenshot1, screenshot2,
                           difference_percent_threshold=5):
        """
        Make sure screenshots are sufficiently different.

        @param screenshot1: path to screenshot.
        @param screenshot2: path to screenshot.
        @param difference_percent_threshold: threshold for difference.

        @returns number of errors found (0 or 1).

        """
        filename1 = screenshot1.split('/')[-1]
        filename2 = screenshot2.split('/')[-1]
        diff = get_percent_difference(screenshot1, screenshot2)
        logging.info("Screenshot 1 and 2 diff: %s" % diff)
        if not diff >= difference_percent_threshold:
            error = ('Screenshots differ by %d %%: %s vs %s'
                     % (diff, filename1, filename2))
            self.ERRORS.append(error)

    def _verify_similarity(self, screenshot1, screenshot2,
                           similarity_percent_threshold=5):
        """
        Make sure screenshots are the same or similar.

        @param screenshot1: path to screenshot.
        @param screenshot2: path to screenshot.
        @param difference_percent_threshold: threshold for similarity.

        @returns number of errors found (0 or 1).

        """
        filename1 = screenshot1.split('/')[-1]
        filename2 = screenshot2.split('/')[-1]
        diff = get_percent_difference(screenshot1, screenshot2)
        logging.info("Screenshot 1 and 2 similarity diff: %s" % diff)
        if not diff <= similarity_percent_threshold:
            error = ('Screenshots differ by %d %%: %s vs %s'
                     % (diff, filename1, filename2))
            self.ERRORS.append(error)

    def run_once(self):
        """
        Run tablet mode test to spoof various tablet modes and ensure
        device changes accordingly.
        """

        # Ensure we start in laptop mode.
        self._revert_laptop()

        logging.info("Take screenshot for initial laptop mode.")
        laptop_start = self._take_screenshot('laptop_start')

        logging.info("Entering landscape mode.")
        self._spoof_tablet_landscape()
        landscape = self._take_screenshot('landscape')

        self._revert_laptop()

        logging.info("Entering portrait mode.")
        self._spoof_tablet_portrait()
        portrait = self._take_screenshot('portrait')

        self._revert_laptop()
        laptop_end = self._take_screenshot('laptop_end')

        # Compare screenshots and determine the number of errors.
        self._verify_similarity(laptop_start, laptop_end)
        self._verify_difference(laptop_start, landscape)
        self._verify_difference(landscape, portrait)
        self._verify_difference(portrait, laptop_end)

        if self.ERRORS:
            raise error.TestFail('; '.join(set(self.ERRORS)))

    def cleanup(self):
        self._revert_laptop()
