# Lint as: python2, python3
# 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

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros.update_engine import nebraska_wrapper
from autotest_lib.client.cros.update_engine import update_engine_test

class autoupdate_EOL(update_engine_test.UpdateEngineTest):
    """Tests end of life (EOL) behaviour."""
    version = 1

    _EXPECTED_FINAL_TITLE = 'Final software update'
    _DAYS_BEFORE_EOL_START_WARNING = 180
    # Value within {} expected to be number of days since epoch.
    _EXPECTED_EOL_DATE_TEMPLATE = 'EOL_DATE={}'
    # Value within {} expected to be the month and year.
    _EXPECTED_WARNING_TITLE = 'Updates end {}'
    _UNIX_EPOCH = datetime.datetime(1970, 1, 1)


    def _get_expected_eol_date(self, eol_date):
        """Figure out the expected eol date."""
        return self._UNIX_EPOCH + datetime.timedelta(eol_date)


    def _check_eol_info(self):
        """Checks update_engines eol status."""
        result = utils.run(
            [self._UPDATE_ENGINE_CLIENT_CMD, '--eol_status']).stdout.strip()
        if self._EXPECTED_EOL_DATE not in result:
            raise error.TestFail('Expected date %s. Actual: %s' %
                                 (self._EXPECTED_EOL_DATE, result))


    def _check_eol_notification(self, eol_date):
        """Checks that we are showing an EOL notification to the user."""
        expected_eol_date = self._get_expected_eol_date(eol_date)
        expected_warning_begins_date = (expected_eol_date
                                        - datetime.timedelta(
                                          self._DAYS_BEFORE_EOL_START_WARNING))

        expected_final_title = self._EXPECTED_FINAL_TITLE
        expected_warning_title = (self._EXPECTED_WARNING_TITLE.
            format(expected_eol_date.strftime("%B %Y")))

        def find_notification(expected_title):
            """Helper to find notification."""
            notifications = self._cr.get_visible_notifications()
            return any([n['title'] == expected_title
                        for n in (notifications or [])])

        def check_eol_notifications():
            """Checks if correct notification is shown."""
            final_notification = find_notification(expected_final_title)
            warning_notification = find_notification(expected_warning_title)

            now = datetime.datetime.utcnow()
            if expected_eol_date <= now:
                return final_notification and not warning_notification
            elif expected_warning_begins_date <= now:
                return not final_notification and warning_notification
            return not final_notification and not warning_notification

        utils.poll_for_condition(condition=lambda: check_eol_notifications(),
                                 desc='End of Life Notification UI passed',
                                 timeout=5, sleep_interval=1)


    def _check_eol_settings(self, eol_date):
        """Check that the messages about EOL in Settings are correct."""
        tab = self._cr.browser.tabs[0]
        tab.Navigate('chrome://os-settings/help/details')
        tab.WaitForDocumentReadyStateToBeComplete()
        eol_js = '''
            async function getEOL() {
                return await import('chrome://os-settings/chromeos/os_settings.js').then(m =>
                    m.AboutPageBrowserProxyImpl.getInstance().getEndOfLifeInfo());
            }
            getEOL();
        '''
        eol_promise = tab.EvaluateJavaScript(eol_js, promise=True)
        expected_eol_date = self._get_expected_eol_date(eol_date)
        eol_msg = ('This device will get automatic software and security '
                   'updates until')
        if expected_eol_date <= datetime.datetime.utcnow():
            eol_msg = ('This device stopped getting automatic software and '
                       'security updates in')
        if eol_msg not in eol_promise['aboutPageEndOfLifeMessage']:
            raise error.TestFail('"%s" not found in Settings.' % eol_msg)


    def run_once(self, eol_date):
        """
        Checks that DUT behaves correctly in EOL scenarios.

        @param eol_date: the days from epoch value passed along to
                         NanoOmahaDevServer placed within the _eol_date tag
                         in the Omaha response.

        """
        self._EXPECTED_EOL_DATE = \
            self._EXPECTED_EOL_DATE_TEMPLATE.format(eol_date)

        # Start a Nebraska server to return a response with eol entry.
        with nebraska_wrapper.NebraskaWrapper(
            log_dir=self.resultsdir) as nebraska:
            # Try to update. It should fail with noupdate.
            try:
                self._check_for_update(
                    nebraska.get_update_url(eol_date=eol_date, no_update=True),
                    wait_for_completion=True)
            except error.CmdError:
                logging.info('Update failed as expected.')

            self._check_eol_info()
            with chrome.Chrome(autotest_ext=True, logged_in=True) as cr:
                self._cr = cr
                self._check_eol_notification(eol_date)
                self._check_eol_settings(eol_date)
