# Copyright (c) 2012 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.

"""This module sets up the system for the touchpad firmware test suite."""

import getopt
import logging
import os
import sys

import firmware_utils
import firmware_window
import keyboard_device
import mtb
import test_conf as conf
import test_flow
import touch_device

from firmware_constants import MODE, OPTIONS
from report_html import ReportHtml


def setup_http_data_dir():
    """Set up the default http data dir for pyauto test.

    When creating a test http server, it checks the default http data dir
    no matter whether it is actually used. If the http data dir does not exist,
    it throws out the testserver_base.OptionError.
    """
    autotest_dir = '/usr/local/autotest'
    pyauto_test_dir = 'deps/pyauto_dep/test_src'
    data_dir = 'chrome/test/data'
    http_data_dir = os.path.join(autotest_dir, pyauto_test_dir, data_dir)
    if not os.path.isdir(http_data_dir):
        try:
            os.makedirs(http_data_dir)
            msg = 'http data directory created successfully: %s'
            logging.info(msg % http_data_dir)
        except os.error, e:
            logging.error('Making the default http data dir: %s.' % e)
            exit(-1)


# Include the paths and import required modules for running pyauto if
# pyauto has been installed so that the test result file could be displayed
# on Chrome automatically when all tests are finished.
pyautolib = '/usr/local/autotest/deps/pyauto_dep/test_src/chrome/test/pyautolib'
is_pyauto_installed = os.path.isdir(pyautolib)
if is_pyauto_installed:
    sys.path.append('/usr/local/autotest/cros')
    sys.path.append(pyautolib)
    import httpd
    import pyauto

    class DummyTest(pyauto.PyUITest):
        """This is a dummpy test class derived from PyUITest to use pyauto tool.
        """
        def test_navigate_to_url(self):
            """Navigate to the html test result file using pyauto."""
            testServer = httpd.HTTPListener(8000, conf.docroot)
            testServer.run()
            # Note that the report_html_name is passed from firmware_TouchpadMTB
            # to DummyTest as an environment variable.
            # It is not passed as a global variable in this module because
            # pyauto seems to create its own global scope.
            report_html_name = os.environ[conf.ENVIRONMENT_REPORT_HTML_NAME]
            if report_html_name:
                base_url = os.path.basename(report_html_name)
                url = os.path.join('http://localhost:8000', base_url)
                self.NavigateToURL(url)
                msg = 'Chrome has navigated to the specified url: %s'
                logging.info(msg % os.path.join(conf.docroot, base_url))
            testServer.stop()


class firmware_TouchpadMTB:
    """Set up the system for touchpad firmware tests."""

    def __init__(self, options):
        # Create the touchpad device.
        self.touchpad = touch_device.TouchpadDevice()
        self._check_device(self.touchpad)

        # Create the keyboard device.
        self.keyboard = keyboard_device.KeyboardDevice()
        self._check_device(self.keyboard)

        # Get the MTB parser.
        self.parser = mtb.MtbParser()

        # Get the chrome browser.
        self.chrome = firmware_utils.SimpleX('aura')

        # Create a simple gtk window.
        self._get_screen_size()
        self._get_touchpad_window_geometry()
        self._get_prompt_frame_geometry()
        self._get_result_frame_geometry()
        self.win = firmware_window.FirmwareWindow(
                size=self.screen_size,
                prompt_size=self.prompt_frame_size,
                image_size=self.touchpad_window_size,
                result_size=self.result_frame_size)

        # Create the HTML report object and the output object to print messages
        # on the window and to print the results in the report.
        firmware_version = self.touchpad.get_firmware_version()
        mode = options[OPTIONS.MODE]
        if options[OPTIONS.RESUME]:
            self.log_dir = options[OPTIONS.RESUME]
        elif options[OPTIONS.REPLAY]:
            self.log_dir = options[OPTIONS.REPLAY]
        else:
            self.log_dir = firmware_utils.create_log_dir(firmware_version, mode)
        self._create_report_name(mode)
        self.report_html = ReportHtml(self.report_html_name,
                                      self.screen_size,
                                      self.touchpad_window_size,
                                      conf.score_colors)
        self.output = firmware_utils.Output(self.log_dir,
                                            self.report_name,
                                            self.win, self.report_html)

        # Get the test_flow object which will guide through the gesture list.
        self.test_flow = test_flow.TestFlow(self.touchpad_window_geometry,
                                            self.touchpad,
                                            self.keyboard,
                                            self.win,
                                            self.parser,
                                            self.output,
                                            options=options)

        # Register some callback functions for firmware window
        self.win.register_callback('expose_event',
                                   self.test_flow.init_gesture_setup_callback)

        # Register a callback function to watch keyboard input events.
        # This is required because the set_input_focus function of a window
        # is flaky maybe due to problems of the window manager.
        # Hence, we handle the keyboard input at a lower level.
        self.win.register_io_add_watch(self.test_flow.user_choice_callback,
                                       self.keyboard.system_device)

        # Stop power management so that the screen does not dim during tests
        firmware_utils.stop_power_management()

    def _check_device(self, device):
        """Check if a device has been created successfully."""
        if device.device_node is None:
            logging.error('Cannot find device_node.')
            exit(-1)

    def _create_report_name(self, mode):
        """Create the report names for both plain-text and html files.

        A typical html file name looks like:
            touchpad_firmware_report-lumpy-fw_11.25-20121016_080924.html
        """
        firmware_str = 'fw_' + self.touchpad.get_firmware_version()
        board = firmware_utils.get_board()
        curr_time = firmware_utils.get_current_time_str()
        fname = conf.filename.sep.join([conf.report_basename,
                                        board,
                                        firmware_str,
                                        mode,
                                        curr_time])
        self.report_name = os.path.join(self.log_dir, fname)
        self.report_html_name = self.report_name + conf.html_ext
        # Pass the report_html_name to DummyTest as an environment variable.
        os.environ[conf.ENVIRONMENT_REPORT_HTML_NAME] = self.report_html_name

    def _get_screen_size(self):
        """Get the screen size."""
        self.screen_size = self.chrome.get_screen_size()

    def _get_touchpad_window_geometry(self):
        """Get the preferred window geometry to display mtplot."""
        display_ratio = 0.7
        self.touchpad_window_geometry = self.touchpad.get_display_geometry(
                self.screen_size, display_ratio)
        self.touchpad_window_size = self.touchpad_window_geometry[0:2]

    def _get_prompt_frame_geometry(self):
        """Get the display geometry of the prompt frame."""
        (_, wint_height, _, _) = self.touchpad_window_geometry
        screen_width, screen_height = self.chrome.get_screen_size()
        win_x = 0
        win_y = 0
        win_width = screen_width
        win_height = screen_height - wint_height
        self.winp_geometry = (win_x, win_y, win_width, win_height)
        self.prompt_frame_size = (win_width, win_height)

    def _get_result_frame_geometry(self):
        """Get the display geometry of the test result frame."""
        (wint_width, wint_height, _, _) = self.touchpad_window_geometry
        screen_width, _ = self.chrome.get_screen_size()
        win_width = screen_width - wint_width
        win_height = wint_height
        self.result_frame_size = (win_width, win_height)

    def main(self):
        """A helper to enter gtk main loop."""
        fw.win.main()
        firmware_utils.start_power_management()
        if is_pyauto_installed:
            setup_http_data_dir()
            pyauto.Main()


def _usage_and_exit():
    """Print the usage of this program."""
    print 'Usage: $ DISPLAY=:0 [OPTIONS="options"] python %s\n' % sys.argv[0]
    print 'options:'
    print '  -h, --%s' % OPTIONS.HELP
    print '        show this help'
    print '  -i, --%s iterations' % OPTIONS.ITERATIONS
    print '        specify the number of iterations'
    print '  -m, --%s mode' % OPTIONS.MODE
    print '        specify the gesture playing mode'
    print '        mode could be one of the following options'
    print '            complete: all gestures including those in ' \
                                'both manual mode and robot mode'
    print '            manual: all gestures minus gestures in robot mode'
    print '            robot: using robot to perform gestures automatically'
    print '            robot_int: using robot with finger interaction'
    print '            robot_sim: robot simulation, for developer only'
    print '  --%s log_dir' % OPTIONS.REPLAY
    print '        Replay the gesture files and get the test results.'
    print '        log_dir is a log sub-directory in %s' % conf.log_root_dir
    print '  --%s log_dir' % OPTIONS.RESUME
    print '        Resume recording the gestures files in the log_dir.'
    print '        log_dir is a log sub-directory in %s' % conf.log_root_dir
    print '  -s, --%s' % OPTIONS.SIMPLIFIED
    print '        Use one variation per gesture'
    print
    print 'Example:'
    print '  # Use the robot to perform 3 iterations of the robot gestures.'
    print '  $ DISPLAY=:0 OPTIONS="-m robot_sim -i 3" python main.py\n'
    print '  # Perform 1 iteration of the manual gestures.'
    print '  $ DISPLAY=:0 OPTIONS="-m manual" python main.py\n'
    print '  # Perform 1 iteration of all manual and robot gestures.'
    print '  $ DISPLAY=:0 OPTIONS="-m complete" python main.py\n'
    print '  # Replay the gesture files in the latest log directory.'
    print '  $ DISPLAY=:0 OPTIONS="--replay latest" python main.py\n'
    example_log_dir = '20130226_040802-fw_1.2-manual'
    print '  # Replay the gesture files in %s/%s' % (conf.log_root_dir,
                                                     example_log_dir)
    print '  $ DISPLAY=:0 OPTIONS="--replay %s" python main.py\n' % \
            example_log_dir

    print '  # Resume recording the gestures in the latest log directory.'
    print '  $ DISPLAY=:0 OPTIONS="--resume latest" python main.py\n'
    print '  # Resume recording the gestures in %s/%s.' % (conf.log_root_dir,
                                                           example_log_dir)
    print '  $ DISPLAY=:0 OPTIONS="--resume %s" python main.py\n' % \
            example_log_dir
    sys.exit(1)


def _parsing_error(msg):
    """Print the usage and exit when encountering parsing error."""
    print 'Error: %s' % msg
    _usage_and_exit()


def _parse_options():
    """Parse the options.

    Note that the options are specified with environment variable OPTIONS,
    because pyauto seems not compatible with command line options.
    """
    # Set the default values of options.
    options = {OPTIONS.ITERATIONS: 1,
               OPTIONS.MODE: MODE.MANUAL,
               OPTIONS.REPLAY: None,
               OPTIONS.RESUME: None,
               OPTIONS.SIMPLIFIED: False}

    # Get the environment OPTIONS
    options_str = os.environ.get('OPTIONS')
    if not options_str:
        return options

    options_list = options_str.split()
    try:
        short_opt = 'hi:m:s'
        long_opt = [OPTIONS.HELP,
                    OPTIONS.ITERATIONS + '=',
                    OPTIONS.MODE + '=',
                    OPTIONS.REPLAY + '=',
                    OPTIONS.RESUME + '=',
                    OPTIONS.SIMPLIFIED]
        opts, args = getopt.getopt(options_list, short_opt, long_opt)
    except getopt.GetoptError, err:
        _parsing_error(str(err))

    for opt, arg in opts:
        if opt in ('-h', '--%s' % OPTIONS.HELP):
            _usage_and_exit()
        elif opt in ('-i', '--%s' % OPTIONS.ITERATIONS):
            if arg.isdigit():
                options[OPTIONS.ITERATIONS] = int(arg)
            else:
                _usage_and_exit()
        elif opt in ('-m', '--%s' % OPTIONS.MODE):
            arg = arg.lower()
            if arg in MODE.GESTURE_PLAY_MODE:
                options[OPTIONS.MODE] = arg
            else:
                print 'Warning: -m should be one of %s' % MODE.GESTURE_PLAY_MODE
        elif opt in ('--%s' % OPTIONS.REPLAY, '--%s' % OPTIONS.RESUME):
            log_dir = os.path.join(conf.log_root_dir, arg)
            if os.path.isdir(log_dir):
                # opt could be either '--replay' or '--resume'.
                # We would like to strip off the '-' on the left hand side.
                options[opt.lstrip('-')] = log_dir
            else:
                print 'Error: the log directory "%s" does not exist.' % log_dir
                _usage_and_exit()
        elif opt in ('-s', '--%s' % OPTIONS.SIMPLIFIED):
            options[OPTIONS.SIMPLIFIED] = True
        else:
            msg = 'This option "%s" is not supported.' % opt
            _parsing_error(opt)

    print 'Note: the %s mode is used.' % options[OPTIONS.MODE]
    return options


if __name__ == '__main__':
    options = _parse_options()
    fw = firmware_TouchpadMTB(options)
    fw.main()
