# 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.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import cros_ui_test

class security_BundledExtensions(cros_ui_test.UITest):
    version = 1


    def load_baseline(self):
        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_names = baseline['ignored_extension_names']
        self._ignored_crx_files = baseline['ignored_crx_files']
        self._bundled_crx_directory = baseline['bundled_crx_directory']
        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.

        Returns:
          A list of dicts, each representing an extension. For more
          information, see the pyauto documentation.
        """
        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['name'] in self._ignored_extension_names:
                filtered_info.append(rec)
        return filtered_info


    def assert_perms_match(self, expected_set, actual_set, perm_type,
                           full_expected_info, full_actual_info):
        """Asserts that the set of permissions for an extension is expected.

        Args:
          expected_set: A set of permissions that are expected to be present.
          actual_set: A set of permissions that are actually present.
          perm_type: A string describing the type of permission involved.
          full_expected_info: A dictionary fully describing the expected
                              information associated with the given extension.
          full_actual_info: A dictionary fully describing the actual
                            information associated with the given extension.
        """
        def _diff_set_msg(expected_set, actual_set):
            strings = []
            for missing_item in expected_set.difference(actual_set):
                strings.append('Missing item: "%s"' % missing_item)
            for extra_item in actual_set.difference(expected_set):
                strings.append('Unexpected (extra) item: "%s"' % extra_item)
            return '\n'.join(strings)

        self.pyauto.assertEqual(
            expected_set, actual_set,
            msg=('%s do not match for "%s".\n'
                 '%s\n'
                 'Expected extension info:\n%s'
                 '\nActual extension info:\n%s' %
                 (perm_type, full_expected_info['name'],
                  _diff_set_msg(expected_set, actual_set),
                  self.pyauto.pformat(full_expected_info),
                  self.pyauto.pformat(full_actual_info))))


    def assert_names_match(self, expected_set, actual_set, ext_type,
                           full_expected_info, full_actual_info):
        """Asserts that a set of extensions is expected.

        Args:
          expected_set: A set of extension names that are expected to be
                        present.
          actual_set: A set of extension names that are actually present.
          ext_type: A string describing the type of extensions involved.
          full_expected_info: A list of dictionaries describing the expected
                              information for all extensions.
          full_actual_info: A list of dictionaries describing the actual
                            information for all extensions.
        """
        def _diff_set_msg(expected_set, actual_set):
            strings = []
            for missing_item in expected_set.difference(actual_set):
                strings.append('Missing item: "%s"' % missing_item)
                located_ext_info = [info for info in full_expected_info if
                                    info['name'] == missing_item][0]
                strings.append(self.pyauto.pformat(located_ext_info))
            for extra_item in actual_set.difference(expected_set):
                strings.append('Unexpected (extra) item: "%s"' % extra_item)
                located_ext_info = [info for info in full_actual_info if
                                    info['name'] == extra_item][0]
                strings.append(self.pyauto.pformat(located_ext_info))
            return '\n'.join(strings)

        self.pyauto.assertEqual(
            expected_set, actual_set,
            msg='%s names do not match the baseline.\n'
                '%s\n' % (ext_type, _diff_set_msg(expected_set, actual_set)))


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

        Args:
          crx_file: A 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 verify_extension_perms(self, baseline):
        """Ensures extension permissions in the baseline match actual info.

        This function will fail the current test if either (1) an
        extension named in the baseline is not currently installed in
        Chrome; or (2) the api permissions or effective host
        permissions of an extension in the baseline do not match the
        actual permissions associated with the extension in Chrome.

        Args:
          baseline: A dictionary of expected extension information, containing
                    extension names and api/effective host permission info.
        """
        full_ext_actual_info = self.get_extensions_info()
        for ext_expected_info in baseline:
            located_ext_info = [info for info in full_ext_actual_info if
                                info['name'] == ext_expected_info['name']]
            self.pyauto.assertTrue(
                located_ext_info,
                msg=('Cannot locate extension info for "%s".\n'
                     'Expected extension info:\n%s' %
                     (ext_expected_info['name'],
                      self.pyauto.pformat(ext_expected_info))))
            ext_actual_info = located_ext_info[0]
            self.assert_perms_match(
                set(ext_expected_info['effective_host_permissions']),
                set(ext_actual_info['effective_host_permissions']),
                'Effective host permissions', ext_expected_info,
                ext_actual_info)
            self.assert_perms_match(
                set(ext_expected_info['api_permissions']),
                set(ext_actual_info['api_permissions']),
                'API permissions', ext_expected_info, ext_actual_info)


    def test_component_extension_permissions(self):
        """Ensures component extension permissions are as expected."""
        expected_names = [ext['name'] for ext in
                          self._component_extension_baseline]
        ext_actual_info = self.get_extensions_info()
        actual_names = [ext['name'] for ext in ext_actual_info if
                        ext['is_component']]
        self.assert_names_match(
            set(expected_names), set(actual_names), 'Component extension',
            self._component_extension_baseline, ext_actual_info)
        self.verify_extension_perms(self._component_extension_baseline)


    def test_bundled_crx_permissions(self):
        """Ensures bundled CRX permissions are as expected."""
        # Verify that each bundled CRX on the device is expected, then
        # install it.
        for file_name in os.listdir(self._bundled_crx_directory):
            if file_name in self._ignored_crx_files:
                logging.debug('Ignoring %s' % file_name)
                continue
            if file_name.endswith('.crx'):
                self.pyauto.assertTrue(
                    file_name in [x['crx_file'] for x in
                                  self._bundled_crx_baseline],
                    msg='Unexpected CRX file: ' + file_name)
                crx_file = os.path.join(self._bundled_crx_directory, file_name)
                self.attempt_install(crx_file)

        # Verify that the permissions information in the baseline matches the
        # permissions associated with the installed bundled CRX extensions.
        self.verify_extension_perms(self._bundled_crx_baseline)


    def test_no_unexpected_extensions(self):
        """Ensures there are no unexpected bundled or component extensions."""
        # Install all bundled extensions on the device.
        for file_name in os.listdir(self._bundled_crx_directory):
            if file_name in self._ignored_crx_files:
                logging.debug('Ignoring %s' % file_name)
                continue
            if file_name.endswith('.crx'):
                crx_file = os.path.join(self._bundled_crx_directory, file_name)
                self.attempt_install(crx_file)
        logging.debug('Done installing extensions')

        # Ensure that the set of installed extension names precisely
        # matches the baseline.
        expected_names = [ext['name'] for ext in
                          self._component_extension_baseline]
        expected_names.extend([ext['name'] for ext in
                               self._bundled_crx_baseline])
        ext_actual_info = self.get_extensions_info()
        installed_names = [ext['name'] for ext in ext_actual_info]
        self.assert_names_match(
            set(expected_names), set(installed_names), 'Installed extension',
            self._component_extension_baseline + self._bundled_crx_baseline,
            ext_actual_info)


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

        # In pyauto this was implemented as 3 different tests, each of
        # which can raise without stopping execution of the other two,
        # and each of which was run in its own clean session.
        # The autotest analogue is to label these in the control file as
        # 3 distinct runs of the test.
        if mode == 'ComponentExtensionPermissions':
            self.test_component_extension_permissions()
        elif mode == 'BundledCrxPermissions':
            self.test_bundled_crx_permissions()
        elif mode == 'NoUnexpectedExtensions':
            self.test_no_unexpected_extensions()
        else:
            error.TestFail('Unimplemented: %s' % mode)
