# Copyright 2018 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 contextlib
import logging

from autotest_lib.client.common_lib import error
from autotest_lib.server import autotest
from autotest_lib.server.cros.tradefed import tradefed_constants as constants


class ChromeLogin(object):
    """Context manager to handle Chrome login state."""

    def need_reboot(self, hard_reboot=False):
        """Marks state as "dirty" - reboot needed during/after test."""
        logging.info('Will reboot DUT when Chrome stops.')
        self._need_reboot = True
        if hard_reboot and self._host.servo:
            self._hard_reboot_on_failure = True

    def __init__(self, host, board=None, dont_override_profile=False,
                 enable_default_apps=False, toggle_ndk=False,
                 nativebridge64=False):
        """Initializes the ChromeLogin object.

        @param board: optional parameter to extend timeout for login for slow
                      DUTs. Used in particular for virtual machines.
        @param dont_override_profile: reuses the existing test profile if any
        @param enable_default_apps: enables default apps (like Files app)
        @param toggle_ndk: toggles native bridge engine switch.
        @param nativebridge64: enables 64-bit native bridge experiment.
        """
        self._host = host
        self._timeout = constants.LOGIN_BOARD_TIMEOUT.get(
            board, constants.LOGIN_DEFAULT_TIMEOUT)
        self._dont_override_profile = dont_override_profile
        self._enable_default_apps = enable_default_apps
        self._need_reboot = False
        self._hard_reboot_on_failure = False
        self._toggle_ndk = toggle_ndk
        self._nativebridge64 = nativebridge64

    def _cmd_builder(self, verbose=False):
        """Gets remote command to start browser with ARC enabled."""
        # If autotest is not installed on the host, as with moblab at times,
        # getting the autodir will raise an exception.
        cmd = autotest.Autotest.get_installed_autodir(self._host)
        cmd += '/bin/autologin.py --arc'

        # We want to suppress the Google doodle as it is not part of the image
        # and can be different content every day interacting with testing.
        cmd += ' --no-startup-window'
        # Disable several forms of auto-installation to stablize the tests.
        cmd += ' --no-arc-syncs'
        # Toggle the translation from houdini to ndk
        if self._toggle_ndk:
            cmd += ' --toggle_ndk'
        if self._dont_override_profile:
            logging.info('Starting Chrome with a possibly reused profile.')
            cmd += ' --dont_override_profile'
        else:
            logging.info('Starting Chrome with a fresh profile.')
        if self._enable_default_apps:
            logging.info('Using --enable_default_apps to start Chrome.')
            cmd += ' --enable_default_apps'
        if self._nativebridge64:
            cmd += ' --nativebridge64'
        if not verbose:
            cmd += ' > /dev/null 2>&1'
        return cmd

    def _login_by_script(self, timeout, verbose):
        """Runs the autologin.py script on the DUT to log in."""
        self._host.run(
            self._cmd_builder(verbose=verbose),
            ignore_status=False,
            verbose=verbose,
            timeout=timeout)

    def _login(self, timeout, verbose=False, install_autotest=False):
        """Logs into Chrome. Raises an exception on failure."""
        if not install_autotest:
            try:
                # Assume autotest to be already installed.
                self._login_by_script(timeout=timeout, verbose=verbose)
            except autotest.AutodirNotFoundError:
                logging.warning('Autotest not installed, forcing install...')
                install_autotest = True

        if install_autotest:
            # Installs the autotest client to the DUT by running a no-op test.
            autotest.Autotest(self._host).run_timed_test(
                'dummy_Pass', timeout=2 * timeout, check_client_result=True)
            # The (re)run the login script.
            self._login_by_script(timeout=timeout, verbose=verbose)

        # Quick check if Android has really started. When autotest client
        # installed on the DUT was partially broken, the script may succeed
        # without actually logging into Chrome/Android. See b/129382439.
        self._host.run(
            # "/data/anr" is an arbitrary directory accessible only after
            # proper login and data mount.
            'android-sh -c "ls /data/anr"',
            ignore_status=False, timeout=9)

    def enter(self):
        """Logs into Chrome with retry."""
        timeout = self._timeout
        try:
            logging.info('Ensure Android is running (timeout=%d)...', timeout)
            self._login(timeout=timeout)
        except Exception as e:
            logging.error('Login failed.', exc_info=e)
            # Retry with more time, with refreshed client autotest installation,
            # and the DUT cleanup by rebooting. This can hide some failures.
            self._reboot()
            timeout *= 2
            logging.info('Retrying failed login (timeout=%d)...', timeout)
            try:
                self._login(timeout=timeout,
                            verbose=True,
                            install_autotest=True)
            except Exception as e2:
                logging.error('Failed to login to Chrome', exc_info=e2)
                raise error.TestError('Failed to login to Chrome')

    def exit(self):
        """On exit restart the browser or reboot the machine."""
        if not self._need_reboot:
            try:
                self._restart()
            except:
                logging.error('Restarting browser has failed.')
                self.need_reboot()
        if self._need_reboot:
            self._reboot()

    def _restart(self):
        """Restart Chrome browser."""
        # We clean up /tmp (which is memory backed) from crashes and
        # other files. A reboot would have cleaned /tmp as well.
        # TODO(ihf): Remove "start ui" which is a nicety to non-ARC tests (i.e.
        # now we wait on login screen, but login() above will 'stop ui' again
        # before launching Chrome with ARC enabled).
        logging.info('Skipping reboot, restarting browser.')
        script = 'stop ui'
        script += '&& find /tmp/ -mindepth 1 -delete '
        script += '&& start ui'
        self._host.run(script, ignore_status=False, verbose=False, timeout=120)

    def _reboot(self):
        """Reboot the machine."""
        if self._hard_reboot_on_failure:
            logging.info('Powering OFF the DUT: %s', self._host)
            self._host.servo.get_power_state_controller().power_off()
            logging.info('Powering ON the DUT: %s', self._host)
            self._host.servo.get_power_state_controller().power_on()
        else:
            logging.info('Rebooting...')
            self._host.reboot()


@contextlib.contextmanager
def login_chrome(hosts, **kwargs):
    """Returns Chrome log-in context manager for multiple hosts. """
    # TODO(pwang): Chromelogin takes 10+ seconds for it to successfully
    #              enter. Parallelize if this becomes a bottleneck.
    instances = [ChromeLogin(host, **kwargs) for host in hosts]
    for instance in instances:
        instance.enter()
    yield instances
    for instance in instances:
        instance.exit()
