# 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.

"""Some utility classes and functions."""

import glob
import os
import re
import sys
import time

import common_util
import test_conf as conf


def get_display_name():
    """Return the display name."""
    return ':0'


def get_current_time_str():
    """Get the string of current time."""
    time_format = '%Y%m%d_%H%M%S'
    return time.strftime(time_format, time.gmtime())


def get_board():
    """Get board of the Chromebook machine."""
    with open('/etc/lsb-release') as lsb:
        context = lsb.read()
    board = None
    if context is not None:
        for line in context.splitlines():
            if line.startswith('CHROMEOS_RELEASE_BOARD'):
                board_str = line.split('=')[1]
                if '-' in board_str:
                    board = board_str.split('-')[1]
                elif '_' in board_str:
                    board = board_str.split('_')[1]
                else:
                    board = board_str
                # Some boards, e.g. alex, may have board name as alex32
                board = re.search('(\D+)\d*', board, re.I).group(1)
                break
    return board


def get_board_from_filename(filename):
    """Get the board name from a given string which is usually a log file.

    A log file looks like:
        touch_firmware_report-lumpy-fw_11.27-complete-20130610_150540.log

    @param filename: the filename used to extract the board
    """
    pieces = filename.split('-')
    return pieces[1] if len(pieces) >= 2 else None

def get_board_from_directory(directory):
    """Get the board name from the log in the replay directory.

    @param directory: the log directory
    """
    log_files = glob.glob(os.path.join(conf.log_root_dir, directory, '*.log'))
    for log_file in log_files:
        board = get_board_from_filename(os.path.basename(log_file))
        if board:
            return board
    return None


def get_cpu():
    """Get the processor of the machine."""
    return common_util.simple_system_output('uname -m')


def install_pygtk():
    """A temporary dirty hack of installing pygtk related packages."""
    pygtk_dict = {'x86_64': ['pygtk_x86_64.tbz2', 'lib64'],
                  'i686': ['pygtk_x86_32.tbz2', 'lib'],
                  'armv7l': ['pygtk_armv7l.tbz2', 'lib'],
    }
    pygtk_info = pygtk_dict.get(get_cpu().lower())

    if get_board() is None:
        print 'This does not look like a chromebook.'
    elif pygtk_info:
        cmd_remount = 'mount -o remount,rw /'
        if common_util.simple_system(cmd_remount) == 0:
            pygtk_tarball, lib_path = pygtk_info
            cmd_untar = 'tar -jxf pygtk/%s -C /' % pygtk_tarball
            if common_util.simple_system(cmd_untar) == 0:
                # Need to add the gtk path manually. Otherwise, the path
                # may not be in the sys.path for the first time when the
                # tarball is extracted.
                gtk_path = ('/usr/local/%s/python2.7/site-packages/gtk-2.0' %
                            lib_path)
                sys.path.append(gtk_path)
                print 'Successful installation of pygtk.'
                return True
            else:
                print 'Error: Failed to install pygtk.'
        else:
            print 'Failed to remount. Have you removed the write protect?'
    else:
        print 'The pygtk is only supported for %s so far.' % pygtk_dict.keys()
        print 'The other cpus will be supported on demand.'
        print 'The plan is to remove gtk totally and upgrade to Chrome browser.'
    return False


def get_fw_and_date(filename):
    """Get the firmware version and the test date from a log directory
       or a log file.

    An example html filename looks like
        'touch_firmware_report-link-fw_1.0.170-manual-20130426_064849.log'
        return (fw_1.0.170, 20130426_064849)

    An example log directory looks like
        '20130422_020631-fw_1.0.170-manual'
        return (fw_1.0.170, 20130422_020631)
    """
    # The firmware could be fw_1.0.170 or fw_1.0.AA which always comes with
    # 'fw_' as its prefix. The character '-' is used to separate components
    # in the filename.
    result = re.search('-(%s[^-]+?)-' % conf.fw_prefix, filename)
    fw = result.group(1) if result else None

    result = re.search('(\d{8}_\d{6})[-.]', filename)
    date = result.group(1) if result else None

    return (fw, date)


def create_log_dir(firmware_version, mode):
    """
    Create a directory to save the report and device event files.

    @param firmware_version: The firmware version.
    @param mode: The mode with which to create the directory.
    """
    dir_basename = conf.filename.sep.join([get_current_time_str(),
                                           conf.fw_prefix + firmware_version,
                                           mode])
    log_root_dir = conf.log_root_dir
    log_dir = os.path.join(log_root_dir, dir_basename)
    latest_symlink = os.path.join(log_root_dir, 'latest')

    # Create the log directory.
    try:
        os.makedirs(log_dir)
    except OSError, e:
        print 'Error in create the directory (%s): %s' % (log_dir, e)
        sys.exit(1)

    # Set up the latest symbolic link to the newly created log directory.
    try:
        if os.path.islink(latest_symlink):
            os.remove(latest_symlink)
        os.symlink(log_dir, latest_symlink)
    except OSError, e:
        print 'Error in setup latest symlink (%s): %s' % (latest_symlink, e)
        sys.exit(1)
    return log_dir


def stop_power_management():
    """Stop the power daemon management."""
    ret_d = common_util.simple_system('stop -q powerd')
    if ret_d:
        print 'Error in stopping powerd.'
        print 'The screen may dim during the test.'


def start_power_management():
    """Start the power daemon management."""
    ret_d = common_util.simple_system('start -q powerd')
    if ret_d:
        print 'Error in starting powerd.'
        print 'The screen may not go into suspend mode.'
        print 'If this is a problem, you could reboot the machine.'


class GestureList:
    """A class defines the gesture list."""

    def __init__(self, gesture_names=None):
        self.gesture_names = (gesture_names if gesture_names
                                            else conf.gesture_names_complete)

    def get_gesture_list(self, key=None):
        """Get the list of Gesture objects based on the gesture names."""
        gesture_dict = conf.get_gesture_dict()
        gesture_list = []
        for name in self.gesture_names:
            gesture = gesture_dict.get(name)
            if gesture is None:
                msg = 'Error: the gesture "%s" is not defined in the config.'
                print msg % name
                return []
            gesture_list.append(gesture)
        return sorted(gesture_list, key=key) if key else gesture_list


class Output:
    """A class to handle outputs to the window and to the report."""
    def __init__(self, log_dir, report_name, win, report_html):
        self.log_dir = log_dir
        self.report_name = report_name
        self.report = open(report_name, 'w')
        self.win = win
        self.prefix_space = ' ' * 4
        self.msg = None
        self.report_html = report_html

    def __del__(self):
        self.stop()

    def stop(self):
        """Close the report file and print it on stdout."""
        self.report.close()
        with open(self.report_name) as f:
            for line in f.read().splitlines():
                print line
        report_msg = '\n*** This test report is saved in the file: %s\n'
        print report_msg % self.report_name

    def get_prefix_space(self):
        """Get the prefix space when printing the report."""
        return self.prefix_space

    def print_report_line(self, msg):
        """
        Print the line with proper indentation.

        @param msg: The line to print.
        """

        self.report.write(self.prefix_space + str(msg) + os.linesep)

    def print_window(self, msg):
        """
        Print the message to the result window.

        @param msg: The line to print.
        """

        if type(msg) is list:
            msg = os.linesep.join(msg)
        self.win.set_result(msg)
        print msg

    def _print_report(self, msg):
        """
        Print the message to the report.

        @param msg: The line to print.
        """

        if type(msg) is list:
            for line in msg:
                self.print_report_line(line)
        else:
            self.print_report_line(msg)

    def buffer_report(self, msg):
        """Buffer the message and print it later if not over-written.

        Usage of the method: the validator test result of a gesture may
        be discarded because the user chooses to re-perform the gesture
        again. So it should be able to over-write the message.

        @param msg: The line to print.
        """

        self.msg = msg

    def flush_report(self):
        """Print the buffered message if any."""
        if self.msg:
            self._print_report(self.msg)
            self.msg = None

    def print_report(self, msg):
        """
        Print the message to the report.

        @param msg: The line to print.
        """

        # Print any buffered message first.
        self.flush_report()
        # Print this incoming message
        self._print_report(msg)

    def print_all(self, msg):
        """
        Print the message to both report and to the window.

        @param msg: The line to print.
        """

        self.print_window(msg)
        self.buffer_report(msg)


#TODO: This class is not Freon-ready!
class ScreenShot:
    """Handle screen shot."""

    def __init__(self, geometry_str):
        self.geometry_str = geometry_str
        environment_str = 'DISPLAY=:0.0 XAUTHORITY=/home/chronos/.Xauthority '
        dump_util = '/usr/local/bin/import -quality 20'
        self.dump_window_format = ' '.join([environment_str, dump_util,
                                           '-window %s %s.png'])
        self.dump_root_format = ' '.join([environment_str, dump_util,
                                         '-window root -crop %s %s.png'])
        self.get_id_cmd = 'DISPLAY=:0 xwininfo -root -tree'

    def dump_window(self, filename):
        """
        Dump the screenshot of a window to the specified file name.

        @param filename: The filename to save the screenshot as.
        """

        win_id = self._get_win_id()
        if win_id:
            dump_cmd = self.dump_window_format % (win_id, filename)
            common_util.simple_system(dump_cmd)
        else:
            print 'Warning: cannot get the window id.'

    def dump_root(self, filename):
        """
        Dump the screenshot of root to the specified file name.

        @param filename: The filename to save the screenshot as.
        """

        dump_cmd = self.dump_root_format % (self.geometry_str, filename)
        common_util.simple_system(dump_cmd)

    def _get_win_id(self):
        """Get the window ID based on the characteristic string."""
        result = common_util.simple_system_output(self.get_id_cmd)
        for line in result.splitlines():
            if self.geometry_str in line:
                return line.split()[0].strip()
        return None
