# Copyright (c) 2012 The Chromium 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 json
import logging
import os

from autotest_lib.client.common_lib import error, site_utils
from autotest_lib.client.cros import cros_ui_test

class security_BundledExtensions(cros_ui_test.UITest):
    """Verify security properties of bundled (on-disk) Extensions."""
    version = 2

    def load_baseline(self):
        """
        Loads the set of expected security properties.

        @return Dictionary of expected security properties
        """
        bfile = open(os.path.join(self.bindir, 'baseline'))
        with open(os.path.join(self.bindir, 'baseline')) as bfile:
            baseline = []
            for line in bfile:
                if not line.startswith('#'):
                    baseline.append(line)
            baseline = json.loads(''.join(baseline))
        self._ignored_extension_ids = baseline['ignored_extension_ids']
        self._bundled_crx_baseline = baseline['bundled_crx_baseline']
        self._component_extension_baseline = baseline[
            'component_extension_baseline']
        self._official_components = baseline['official_components']


    def get_extensions_info(self):
        """
        Wraps the pyauto method GetExtensionsInfo().

        Filters out extensions that are on the to-be-ignored list.

        @return list of dicts, each representing an extension
        """
        complete_info = self.pyauto.GetExtensionsInfo()
        logging.debug("GetExtensionsInfo:\n%s",
                      self.pyauto.pformat(complete_info))
        filtered_info = []
        for rec in complete_info:
            if not rec['id'] in self._ignored_extension_ids:
                filtered_info.append(rec)
        return filtered_info


    def attempt_install(self, crx_file):
        """Try to install a crx, and log an error if it fails.

        @param crx_file string containing the path to a .crx file
        """
        # This helps limit the degree to which future bugs like
        # crbug.com/131480 interfere with testing. The test will still
        # fail, but at least the test will complete (and notice any
        # problems in any *other* extensions).
        import pyauto_errors
        logging.debug('Installing %s', crx_file)
        try:
            self.pyauto.InstallExtension(crx_file, from_webstore=True)
        except pyauto_errors.JSONInterfaceError:
            logging.error('Installation failed for %s', crx_file)


    def install_all(self, crx_dirs):
        """
        Install all crx's located in crx_dirs

        @param crx_dirs a list of strings, each a path to a directory
        """
        for crx_dir in crx_dirs:
            if not os.path.exists(crx_dir):
                continue
            for file_name in os.listdir(crx_dir):
                if not file_name.endswith('.crx'):
                    continue
                crx_id = self.crx_id_from_filename(file_name)
                if crx_id in self._ignored_extension_ids:
                    logging.debug('Ignoring %s', file_name)
                    continue
                self.attempt_install(os.path.join(crx_dir, file_name))
        logging.debug('Done installing extensions')


    def crx_id_from_filename(self, filename):
        """
        Obtain the id of a crx, given its filename.

        @param filename the name of the crx file

        @return the crx id
        """
        return filename.split('.crx')[0]


    def install_and_compare(self):
        """Install all extensions and compare to the expected set."""
        test_fail = False
        # Install all bundled extensions on the device.
        # Per crbug.com/275052 these all now live here:
        self.install_all(['/var/cache/external_cache/extensions'])

        # * Find the set of expected IDs.
        # * Find the set of observed IDs.
        # * Do set comparison to find the unexpected, and the expected/missing.
        combined_baseline = (self._bundled_crx_baseline +
                             self._component_extension_baseline)
        # Filter out any baseline entries that don't apply to this board.
        # If there is no 'boards' limiter on a given record, the record applies.
        # If there IS a 'boards' limiter, check that it applies.
        board = site_utils.get_current_board()
        combined_baseline = [x for x in combined_baseline
                             if ((not 'boards' in x) or
                                 ('boards' in x and board in x['boards']))]

        observed_extensions = self.get_extensions_info()
        observed_ids = set([x['id'] for x in observed_extensions])
        expected_ids = set([x['id'] for x in combined_baseline])

        missing_ids = expected_ids - observed_ids
        missing_names = ['%s (%s)' % (x['name'], x['id'])
                         for x in combined_baseline if x['id'] in missing_ids]

        unexpected_ids = observed_ids - expected_ids
        unexpected_names = ['%s (%s)' % (x['name'], x['id'])
                            for x in observed_extensions if
                            x['id'] in unexpected_ids]

        good_ids = expected_ids.intersection(observed_ids)

        if missing_names:
            logging.error('Missing: %s', '; '.join(missing_names))
            test_fail = True
        if unexpected_names:
            logging.error('Unexpected: %s', '; '.join(unexpected_names))
            test_fail = True

        # For those IDs in both the expected-and-observed, ie, "good":
        #   Compare sets of expected-vs-actual API permissions, report diffs.
        #   Do same for host permissions.
        for good_id in good_ids:
            baseline = [x for x in combined_baseline if x['id'] == good_id][0]
            actual = [x for x in observed_extensions if x['id'] == good_id][0]
            # Check the API permissions.
            baseline_apis = set(baseline['api_permissions'])
            actual_apis = set(actual['api_permissions'])
            missing_apis = baseline_apis - actual_apis
            unexpected_apis = actual_apis - baseline_apis
            if missing_apis or unexpected_apis:
                test_fail = True
                self._report_attribute_diffs(missing_apis, unexpected_apis,
                                             actual)
            # Check the host permissions.
            baseline_hosts = set(baseline['effective_host_permissions'])
            actual_hosts = set(actual['effective_host_permissions'])
            missing_hosts = baseline_hosts - actual_hosts
            unexpected_hosts = actual_hosts - baseline_hosts
            if missing_hosts or unexpected_hosts:
                test_fail = True
                self._report_attribute_diffs(missing_hosts, unexpected_hosts,
                                             actual)
        if test_fail:
            raise error.TestFail('Bundled extensions mismatch, see error log.')


    def _report_attribute_diffs(self, missing, unexpected, rec):
        logging.error('Problem with %s (%s):', rec['name'], rec['id'])
        if missing:
            logging.error('It no longer uses: %s', '; '.join(missing))
        if unexpected:
            logging.error('It unexpectedly uses: %s', '; '.join(unexpected))


    def run_once(self, mode=None):
        self.load_baseline()
        if self.pyauto.GetBrowserInfo()['properties']['is_official']:
            self._component_extension_baseline.extend(self._official_components)

        self.install_and_compare()
