# 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 datetime
import logging
import os
import re
import shutil
import time
import urlparse

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.common_lib.cros import kernel_utils
from autotest_lib.client.cros.update_engine import update_engine_event

_DEFAULT_RUN = utils.run
_DEFAULT_COPY = shutil.copy

class UpdateEngineUtil(object):
    """
    Utility code shared between client and server update_engine autotests.

    All update_engine autotests inherit from either the client or server
    version of update_engine_test:
    client/cros/update_engine/update_engine_test.py
    server/cros/update_engine/update_engine_test.py

    These update_engine_test classes inherit from test and update_engine_util.
    For update_engine_util to work seamlessly, we need the client and server
    update_engine_tests to define _run() and _get_file() functions:
    server side: host.run and host.get_file
    client side: utils.run and shutil.copy

    """

    # Update engine status lines.
    _PROGRESS = 'PROGRESS'
    _CURRENT_OP = 'CURRENT_OP'

    # Source version when we force an update.
    _FORCED_UPDATE = 'ForcedUpdate'

    # update_engine_client command
    _UPDATE_ENGINE_CLIENT_CMD = 'update_engine_client'

    # Update engine statuses.
    _UPDATE_STATUS_IDLE = 'UPDATE_STATUS_IDLE'
    _UPDATE_STATUS_CHECKING_FOR_UPDATE = 'UPDATE_STATUS_CHECKING_FOR_UPDATE'
    _UPDATE_STATUS_UPDATE_AVAILABLE = 'UPDATE_STATUS_UPDATE_AVAILABLE'
    _UPDATE_STATUS_DOWNLOADING = 'UPDATE_STATUS_DOWNLOADING'
    _UPDATE_STATUS_FINALIZING = 'UPDATE_STATUS_FINALIZING'
    _UPDATE_STATUS_UPDATED_NEED_REBOOT = 'UPDATE_STATUS_UPDATED_NEED_REBOOT'
    _UPDATE_STATUS_REPORTING_ERROR_EVENT = 'UPDATE_STATUS_REPORTING_ERROR_EVENT'

    # Files used by the tests.
    _UPDATE_ENGINE_LOG = '/var/log/update_engine.log'
    _UPDATE_ENGINE_LOG_DIR = '/var/log/update_engine/'
    _CUSTOM_LSB_RELEASE = '/mnt/stateful_partition/etc/lsb-release'
    _UPDATE_ENGINE_PREFS_DIR = '/var/lib/update_engine/prefs/'

    # Update engine prefs
    _UPDATE_CHECK_RESPONSE_HASH = 'update-check-response-hash'

    # Interrupt types supported in AU tests.
    _REBOOT_INTERRUPT = 'reboot'
    _SUSPEND_INTERRUPT = 'suspend'
    _NETWORK_INTERRUPT = 'network'
    _SUPPORTED_INTERRUPTS = [_REBOOT_INTERRUPT, _SUSPEND_INTERRUPT,
                             _NETWORK_INTERRUPT]

    # Public key used to force update_engine to verify omaha response data on
    # test images.
    _IMAGE_PUBLIC_KEY = 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFxZE03Z25kNDNjV2ZRenlydDE2UQpESEUrVDB5eGcxOE9aTys5c2M4aldwakMxekZ0b01Gb2tFU2l1OVRMVXArS1VDMjc0ZitEeElnQWZTQ082VTVECkpGUlBYVXp2ZTF2YVhZZnFsalVCeGMrSlljR2RkNlBDVWw0QXA5ZjAyRGhrckduZi9ya0hPQ0VoRk5wbTUzZG8Kdlo5QTZRNUtCZmNnMUhlUTA4OG9wVmNlUUd0VW1MK2JPTnE1dEx2TkZMVVUwUnUwQW00QURKOFhtdzRycHZxdgptWEphRm1WdWYvR3g3K1RPbmFKdlpUZU9POUFKSzZxNlY4RTcrWlppTUljNUY0RU9zNUFYL2xaZk5PM1JWZ0cyCk83RGh6emErbk96SjNaSkdLNVI0V3daZHVobjlRUllvZ1lQQjBjNjI4NzhxWHBmMkJuM05wVVBpOENmL1JMTU0KbVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=='


    def __init__(self, run_func=_DEFAULT_RUN, get_file=_DEFAULT_COPY):
        """
        Initialize this class with _run() and _get_file() functions.

        @param run_func: the function to use to run commands on the client.
                         Defaults for use by client tests, but can be
                         overwritten to run remotely from a server test.
        @param get_file: the function to use when copying a file.  Defaults
                         for use by client tests.  Called with
                         (file, destination) syntax.

        """
        self._set_util_functions(run_func, get_file)


    def _set_util_functions(self, run_func=_DEFAULT_RUN,
                            get_file=_DEFAULT_COPY):
        """See __init__()."""
        self._run = run_func
        self._get_file = get_file


    def _wait_for_progress(self, progress):
        """
        Waits until we reach the percentage passed as the input.

        @param progress: The progress [0.0 .. 1.0] we want to wait for.
        """
        while True:
            completed = self._get_update_progress()
            logging.debug('Checking if %s is greater than %s', completed,
                          progress)
            if completed >= progress:
                break
            time.sleep(1)


    def _is_update_started(self):
        """Checks if the update has started."""
        status = self._get_update_engine_status()
        if status is None:
            return False
        return status[self._CURRENT_OP] in (
            self._UPDATE_STATUS_DOWNLOADING, self._UPDATE_STATUS_FINALIZING)


    def _has_progress_stopped(self):
        """Checks that the update_engine progress has stopped moving."""
        before = self._get_update_engine_status()[self._PROGRESS]
        for i in range(0, 10):
            if before != self._get_update_engine_status()[self._PROGRESS]:
                return False
            time.sleep(1)
        return True


    def _get_update_progress(self):
        """Returns the current payload downloaded progress."""
        while True:
            status = self._get_update_engine_status()
            if not status:
                continue
            if self._is_update_engine_idle(status):
                err_str = self._get_last_error_string()
                raise error.TestFail('Update status was idle while trying to '
                                     'get download status. Last error: %s' %
                                     err_str)
            if self._is_update_engine_reporting_error(status):
                err_str = self._get_last_error_string()
                raise error.TestFail('Update status reported error: %s' %
                                     err_str)
            # When the update has moved to the final stages, update engine
            # displays progress as 0.0  but for our needs we will return 1.0
            if self._is_update_finished_downloading(status):
                return 1.0
            # If we call this right after reboot it may not be downloading yet.
            if status[self._CURRENT_OP] != self._UPDATE_STATUS_DOWNLOADING:
                time.sleep(1)
                continue
            return float(status[self._PROGRESS])


    def _wait_for_update_to_fail(self):
        """Waits for the update to retry until failure."""
        timeout_minutes = 20
        timeout = time.time() + 60 * timeout_minutes
        while True:
            if self._check_update_engine_log_for_entry('Reached max attempts ',
                                                       raise_error=False):
                logging.debug('Found log entry for failed update.')
                if self._is_update_engine_idle():
                    break
            time.sleep(1)
            self._get_update_engine_status()
            if time.time() > timeout:
                raise error.TestFail('Update did not fail as expected. Timeout'
                                     ': %d minutes.' % timeout_minutes)


    def _wait_for_update_to_complete(self, check_kernel_after_update=True):
        """
        Wait for update status to reach NEED_REBOOT.

        @param check_kernel_after_update: True to also check kernel state after
                                          the update.

        """
        self._wait_for_update_status(self._UPDATE_STATUS_UPDATED_NEED_REBOOT)
        if check_kernel_after_update:
          kernel_utils.verify_kernel_state_after_update(
              self._host if hasattr(self, '_host') else None)


    def _wait_for_update_status(self, status_to_wait_for):
        """
        Wait for the update to reach a certain status.

        @param status_to_wait_for: a string of the update status to wait for.

        """
        while True:
            status = self._get_update_engine_status()

            # During reboot, status will be None
            if status is not None:
                if self._is_update_engine_reporting_error(status):
                    err_str = self._get_last_error_string()
                    raise error.TestFail('Update status reported error: %s' %
                                         err_str)
                if self._is_update_engine_idle(status):
                    err_str = self._get_last_error_string()
                    raise error.TestFail('Update status was unexpectedly '
                                         'IDLE when we were waiting for the '
                                         'update to complete: %s' % err_str)
                if status[self._CURRENT_OP] == status_to_wait_for:
                    break
            time.sleep(1)


    def _get_update_engine_status(self, timeout=3600, ignore_timeout=True):
        """
        Gets a dictionary version of update_engine_client --status.

        @param timeout: How long to wait for the status to return.
        @param ignore_timeout: True to throw an exception if timeout occurs.

        @return Dictionary of values within update_engine_client --status.
        @raise: error.AutoservError if command times out

        """
        status = self._run([self._UPDATE_ENGINE_CLIENT_CMD, '--status'],
                           timeout=timeout, ignore_status=True,
                           ignore_timeout=ignore_timeout)

        if status is None:
            return None
        logging.info(status)
        if status.exit_status != 0:
            return None
        status_dict = {}
        for line in status.stdout.splitlines():
            entry = line.partition('=')
            status_dict[entry[0]] = entry[2]
        return status_dict


    def _check_update_engine_log_for_entry(self, entry, raise_error=False,
                                           err_str=None,
                                           update_engine_log=None):
        """
        Checks for entries in the update_engine log.

        @param entry: String or tuple of strings to search for.
        @param raise_error: Fails tests if log doesn't contain entry.
        @param err_str: The error string to raise if we cannot find entry.
        @param update_engine_log: Update engine log string you want to
                                  search. If None, we will read from the
                                  current update engine log.

        @return Boolean if the update engine log contains the entry.

        """
        if isinstance(entry, str):
            # Create a tuple of strings so we can iterate over it.
            entry = (entry,)

        if not update_engine_log:
            update_engine_log = self._get_update_engine_log()

        if all(msg in update_engine_log for msg in entry):
            return True

        if not raise_error:
            return False

        error_str = ('Did not find expected string(s) in update_engine log: '
                     '%s' % entry)
        logging.debug(error_str)
        raise error.TestFail(err_str if err_str else error_str)


    def _is_update_finished_downloading(self, status=None):
        """
        Checks if the update has moved to the final stages.

        @param status: Output of _get_update_engine_status(). If None that
                       function will be called here first.

        """
        if status is None:
            status = self._get_update_engine_status()
        return status[self._CURRENT_OP] in [
            self._UPDATE_STATUS_FINALIZING,
            self._UPDATE_STATUS_UPDATED_NEED_REBOOT]


    def _is_update_engine_idle(self, status=None):
        """
        Checks if the update engine is idle.

        @param status: Output of _get_update_engine_status(). If None that
                       function will be called here first.

        """
        if status is None:
            status = self._get_update_engine_status()
        return status[self._CURRENT_OP] == self._UPDATE_STATUS_IDLE


    def _is_checking_for_update(self, status=None):
        """
        Checks if the update status is still checking for an update.

        @param status: Output of _get_update_engine_status(). If None that
                       function will be called here first.

        """
        if status is None:
            status = self._get_update_engine_status()
        return status[self._CURRENT_OP] in (
            self._UPDATE_STATUS_CHECKING_FOR_UPDATE,
            self._UPDATE_STATUS_UPDATE_AVAILABLE)


    def _is_update_engine_reporting_error(self, status=None):
        """
        Checks if the update engine status reported an error.

        @param status: Output of _get_update_engine_status(). If None that
                       function will be called here first.

        """
        if status is None:
            status = self._get_update_engine_status()
        return (status[self._CURRENT_OP] ==
                self._UPDATE_STATUS_REPORTING_ERROR_EVENT)


    def _update_continued_where_it_left_off(self, progress,
                                            reboot_interrupt=False):
        """
        Checks that the update did not restart after an interruption.

        When testing a reboot interrupt we can do additional checks on the
        logs before and after reboot to see if the update resumed.

        @param progress: The progress the last time we checked.
        @param reboot_interrupt: True if we are doing a reboot interrupt test.

        @returns True if update continued. False if update restarted.

        """
        completed = self._get_update_progress()
        logging.info('New value: %f, old value: %f', completed, progress)
        if completed >= progress:
            return True

        # Sometimes update_engine will continue an update but the first reported
        # progress won't be correct. So check the logs for resume info.
        if not reboot_interrupt or not self._check_update_engine_log_for_entry(
            'Resuming an update that was previously started'):
            return False

        # Find the reported Completed and Resumed progress.
        pattern = ('(.*)/(.*) operations \((.*)%\), (.*)/(.*) bytes downloaded'
                   ' \((.*)%\), overall progress (.*)%')
        before_pattern = 'Completed %s' % pattern
        before_log = self._get_update_engine_log(r_index=1)
        before_match = re.findall(before_pattern, before_log)[-1]
        after_pattern = 'Resuming after %s' % pattern
        after_log = self._get_update_engine_log(r_index=0)
        after_match = re.findall(after_pattern, after_log)[0]
        logging.debug('Progress before interrupt: %s', before_match)
        logging.debug('Progress after interrupt: %s', after_match)

        # Check the Resuming progress is greater than Completed progress.
        for i in range(0, len(before_match)):
            logging.debug('Comparing %d and %d', int(before_match[i]),
                          int(after_match[i]))
            if int(before_match[i]) > int(after_match[i]):
              return False
        return True


    def _append_query_to_url(self, url, query_dict):
        """
        Appends the dictionary kwargs to the URL url as query string.

        This function will replace the already existing query strings in url
        with the ones in the input dictionary. I also removes keys that have
        a None value.

        @param url: The given input URL.
        @param query_dicl: A dictionary of key/values to be converted to query
                           string.
        @return: The same input URL url but with new query string items added.

        """
        # TODO(ahassani): This doesn't work (or maybe should not) for queries
        # with multiple values for a specific key.
        parsed_url = list(urlparse.urlsplit(url))
        parsed_query = urlparse.parse_qs(parsed_url[3])
        for k, v in query_dict.items():
            parsed_query[k] = [v]
        parsed_url[3] = '&'.join(
            '%s=%s' % (k, v[0]) for k, v in parsed_query.items()
            if v[0] is not None)
        return urlparse.urlunsplit(parsed_url)


    def _check_for_update(self, update_url, interactive=True,
                          wait_for_completion=False,
                          check_kernel_after_update=True, **kwargs):
        """
        Starts a background update check.

        @param update_url: The URL to get an update from.
        @param interactive: True if we are doing an interactive update.
        @param wait_for_completion: True for --update, False for
                --check_for_update.
        @param check_kernel_after_update: True to check kernel state after a
                successful update. False to skip. wait_for_completion must also
                be True.
        @param kwargs: The dictionary to be converted to a query string and
                appended to the end of the update URL. e.g:
                {'critical_update': True, 'foo': 'bar'} ->
                'http:/127.0.0.1:8080/update?critical_update=True&foo=bar' Look
                at nebraska.py or devserver.py for the list of accepted
                values. If there was already query string in update_url, it will
                append the new values and override the old ones.

        """
        update_url = self._append_query_to_url(update_url, kwargs)
        cmd = [self._UPDATE_ENGINE_CLIENT_CMD,
               '--update' if wait_for_completion else '--check_for_update',
               '--omaha_url=%s' % update_url]

        if not interactive:
            cmd.append('--interactive=false')
        self._run(cmd, ignore_status=False)
        if wait_for_completion and check_kernel_after_update:
            kernel_utils.verify_kernel_state_after_update(
                self._host if hasattr(self, '_host') else None)


    def _rollback(self, powerwash=False):
        """
        Perform a rollback of rootfs.

        @param powerwash: True to powerwash along with the rollback.

        """
        cmd = [self._UPDATE_ENGINE_CLIENT_CMD, '--rollback', '--follow']
        if not powerwash:
            cmd.append('--nopowerwash')
        logging.info('Performing rollback with cmd: %s.', cmd)
        self._run(cmd)
        kernel_utils.verify_kernel_state_after_update(self._host)


    def _restart_update_engine(self, ignore_status=False):
        """
        Restarts update-engine.

        @param ignore_status: True to not raise exception on command failure.

        """
        self._run(['restart', 'update-engine'], ignore_status=ignore_status)


    def _save_extra_update_engine_logs(self, number_of_logs):
        """
        Get the last X number of update_engine logs on the DUT.

        @param number_of_logs: The number of logs to save.

        """
        files = self._get_update_engine_logs()

        for i in range(number_of_logs if number_of_logs <= len(files) else
                       len(files)):
            file = os.path.join(self._UPDATE_ENGINE_LOG_DIR, files[i])
            self._get_file(file, self.resultsdir)


    def _get_update_engine_logs(self, timeout=3600, ignore_timeout=True):
        """
        Helper function to return the list of files in /var/log/update_engine/.

        @param timeout: How many seconds to wait for command to complete.
        @param ignore_timeout: True if we should not throw an error on timeout.

        """
        cmd = ['ls', '-t', '-1', self._UPDATE_ENGINE_LOG_DIR]
        return self._run(cmd, timeout=timeout,
                         ignore_timeout=ignore_timeout).stdout.splitlines()


    def _get_update_engine_log(self, r_index=0, timeout=3600,
                               ignore_timeout=True):
        """
        Returns the last r_index'th update_engine log.

        @param r_index: The index of the last r_index'th update_engine log
                in order they were created. For example:
                  0 -> last one.
                  1 -> second to last one.
        @param timeout: How many seconds to wait for command to complete.
        @param ignore_timeout: True if we should not throw an error on timeout.

        """
        files = self._get_update_engine_logs()
        log_file = os.path.join(self._UPDATE_ENGINE_LOG_DIR, files[r_index])
        return self._run(['cat', log_file]).stdout


    def _create_custom_lsb_release(self, update_url, build='0.0.0.0', **kwargs):
        """
        Create a custom lsb-release file.

        In order to tell OOBE to ping a different update server than the
        default we need to create our own lsb-release. We will include a
        deserver update URL.

        @param update_url: String of url to use for update check.
        @param build: String of the build number to use. Represents the
                      Chrome OS build this device thinks it is on.
        @param kwargs: A dictionary of key/values to be made into a query string
                       and appended to the update_url

        """
        update_url = self._append_query_to_url(update_url, kwargs)

        self._run(['mkdir', os.path.dirname(self._CUSTOM_LSB_RELEASE)],
                  ignore_status=True)
        self._run(['touch', self._CUSTOM_LSB_RELEASE])
        self._run(['echo', 'CHROMEOS_RELEASE_VERSION=%s' % build, '>',
                   self._CUSTOM_LSB_RELEASE])
        self._run(['echo', 'CHROMEOS_AUSERVER=%s' % update_url, '>>',
                   self._CUSTOM_LSB_RELEASE])


    def _clear_custom_lsb_release(self):
        """
        Delete the custom release file, if any.

        Intended to clear work done by _create_custom_lsb_release().

        """
        self._run(['rm', self._CUSTOM_LSB_RELEASE], ignore_status=True)


    def _remove_update_engine_pref(self, pref):
        """
        Delete an update_engine pref file.

        @param pref: The pref file to delete

        """
        pref_file = os.path.join(self._UPDATE_ENGINE_PREFS_DIR, pref)
        self._run(['rm', pref_file], ignore_status=True)


    def _get_update_requests(self):
        """
        Get the contents of all the update requests from the most recent log.

        @returns: a sequential list of <request> xml blocks or None if none.

        """
        update_log = self._get_update_engine_log()

        # Matches <request ... /request>.  The match can be on multiple
        # lines and the search is not greedy so it only matches one block.
        return re.findall(r'<request.*?/request>', update_log, re.DOTALL)


    def _get_time_of_last_update_request(self):
        """
        Get the time of the last update request from most recent logfile.

        @returns: seconds since epoch of when last update request happened
                  (second accuracy), or None if no such timestamp exists.

        """
        update_log = self._get_update_engine_log()

        # Matches any single line with "MMDD/HHMMSS ... Request ... xml", e.g.
        # "[0723/133526:INFO:omaha_request_action.cc(794)] Request: <?xml".
        result = re.findall(r'([0-9]{4}/[0-9]{6}).*Request.*xml', update_log)
        if not result:
            return None

        LOG_TIMESTAMP_FORMAT = '%m%d/%H%M%S'
        match = result[-1]

        # The log does not include the year, so set it as this year.
        # This assumption could cause incorrect behavior, but is unlikely to.
        current_year = datetime.datetime.now().year
        log_datetime = datetime.datetime.strptime(match, LOG_TIMESTAMP_FORMAT)
        log_datetime = log_datetime.replace(year=current_year)

        return time.mktime(log_datetime.timetuple())


    def _take_screenshot(self, filename):
        """
        Take a screenshot and save in resultsdir.

        @param filename: The name of the file to save

        """
        try:
            file_location = os.path.join('/tmp', filename)
            self._run(['screenshot', file_location])
            self._get_file(file_location, self.resultsdir)
        except (error.AutoservRunError, error.CmdError):
            logging.exception('Failed to take screenshot.')


    def _get_last_error_string(self):
        """
        Gets the last error message in the update engine log.

        @returns: The error message.

        """
        err_str = 'Updating payload state for error code: '
        log = self._get_update_engine_log().splitlines()
        targets = [line for line in log if err_str in line]
        logging.debug('Error lines found: %s', targets)
        if not targets:
          return None
        else:
          return targets[-1].rpartition(err_str)[2]


    def _get_latest_initial_request(self):
        """
        Return the most recent initial update request.

        AU requests occur in a chain of messages back and forth, e.g. the
        initial request for an update -> the reply with the update -> the
        report that install has started -> report that install has finished,
        etc.  This function finds the first request in the latest such chain.

        This message has no eventtype listed, or is rebooted_after_update
        type (as an artifact from a previous update since this one).
        Subsequent messages in the chain have different eventtype values.

        @returns: string of the entire update request or None.

        """
        requests = self._get_update_requests()
        if not requests:
            return None

        MATCH_STR = r'eventtype="(.*?)"'
        for i in xrange(len(requests) - 1, -1, -1):
            search = re.search(MATCH_STR, requests[i])
            if (not search or
                (search.group(1) ==
                 str(update_engine_event.EVENT_TYPE_REBOOTED_AFTER_UPDATE))):
                return requests[i]

        return None
