# Copyright (c) 2013 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 os
import logging

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest

TARGET_BIOS = 'host_firmware'
TARGET_EC = 'ec_firmware'

FMAP_AREA_NAMES = [
    'name',
    'offset',
    'size'
]

EXPECTED_FMAP_TREE_BIOS = {
  'WP_RO': {
    'RO_SECTION': {
      'FMAP': {},
      'GBB': {},
      'RO_FRID': {},
    },
    'RO_VPD': {},
  },
  'RW_SECTION_A': {
    'VBLOCK_A': {},
    'FW_MAIN_A': {},
    'RW_FWID_A': {},
  },
  'RW_SECTION_B': {
    'VBLOCK_B': {},
    'FW_MAIN_B': {},
    'RW_FWID_B': {},
  },
  'RW_VPD': {},
}

EXPECTED_FMAP_TREE_EC = {
  'WP_RO': {
    'EC_RO': {
      'FMAP': {},
      'RO_FRID': {},
    },
  },
  'EC_RW': {
    'RW_FWID': {},
  },
}

class firmware_FMap(FirmwareTest):
    """Provides access to firmware FMap"""

    _TARGET_AREA = {
        TARGET_BIOS: [],
        TARGET_EC: [],
    }

    _EXPECTED_FMAP_TREE = {
        TARGET_BIOS: EXPECTED_FMAP_TREE_BIOS,
        TARGET_EC: EXPECTED_FMAP_TREE_EC,
    }

    """Client-side FMap test.

    This test checks the active BIOS and EC firmware contains the required
    FMap areas and verifies their hierarchies. It relies on flashrom to dump
    the active BIOS and EC firmware and dump_fmap to decode them.
    """
    version = 1

    def initialize(self, host, cmdline_args, dev_mode=False):
        super(firmware_FMap, self).initialize(host, cmdline_args)

    def run_cmd(self, command):
        """
        Log and execute command and return the output.

        @param command: Command to executeon device.
        @returns the output of command.

        """
        logging.info('Execute %s', command)
        output = self.faft_client.system.run_shell_command_get_output(command)
        logging.info('Output %s', output)
        return output

    def get_areas(self):
        """Get a list of dicts containing area names, offsets, and sizes
        per device.

        It fetches the FMap data from the active firmware via mosys.
        Stores the result in the appropriate _TARGET_AREA.
        """
        lines = self.run_cmd("mosys eeprom map")

        # The above output is formatted as:
        # name1 offset1 size1
        # name2 offset2 size2
        # ...
        # Convert it to a list of dicts like:
        # [{'name': name1, 'offset': offset1, 'size': size1},
        #  {'name': name2, 'offset': offset2, 'size': size2}, ...]
        for line in lines:
            row = map(lambda s:s.strip(), line.split('|'))
            self._TARGET_AREA[row[0]].append(
                dict(zip(FMAP_AREA_NAMES, [row[1], row[2], row[3]])))


    def _is_bounded(self, region, bounds):
        """Is the given region bounded by the given bounds?"""
        return ((bounds[0] <= region[0] < bounds[1]) and
                (bounds[0] < region[1] <= bounds[1]))


    def _is_overlapping(self, region1, region2):
        """Is the given region1 overlapping region2?"""
        return (min(region1[1], region2[1]) > max(region1[0], region2[0]))


    def check_section(self):
        """Check RW_SECTION_[AB] and RW_LEGACY.

        1- check RW_SECTION_[AB] exist, non-zero, same size
        2- RW_LEGACY exist and > 1MB in size
        """
        # Parse map into dictionary.
        bios = {}
        for e in self._TARGET_AREA[TARGET_BIOS]:
           bios[e['name']] = {'offset': e['offset'], 'size': e['size']}
        succeed = True
        # Check RW_SECTION_[AB] sections.
        if 'RW_SECTION_A' not in bios:
            succeed = False
            logging.error('Missing RW_SECTION_A section in FMAP')
        elif 'RW_SECTION_B' not in bios:
            succeed = False
            logging.error('Missing RW_SECTION_B section in FMAP')
        else:
            if bios['RW_SECTION_A']['size'] != bios['RW_SECTION_B']['size']:
                succeed = False
                logging.error('RW_SECTION_A size != RW_SECTION_B size')
            if (bios['RW_SECTION_A']['size'] == 0
                or bios['RW_SECTION_B']['size'] == 0):
                succeed = False
                logging.error('RW_SECTION_A size or RW_SECTION_B size == 0')
        # Check RW_LEGACY section.
        if 'RW_LEGACY' not in bios:
            succeed = False
            logging.error('Missing RW_LEGACY section in FMAP')
        else:
            if bios['RW_LEGACY']['size'] < 1024*1024:
                succeed = False
                logging.error('RW_LEGACY size is < 1M')
        if not succeed:
            raise error.TestFail('SECTION check failed.')


    def check_areas(self, areas, expected_tree, bounds=None):
        """Check the given area list met the hierarchy of the expected_tree.

        It checks all areas in the expected tree are existed and non-zero sized.
        It checks all areas in sub-trees are bounded by the region of the root
        node. It also checks all areas in child nodes are mutually exclusive.

        @param areas: A list of dicts containing area names, offsets, and sizes.
        @param expected_tree: A hierarchy dict of the expected FMap tree.
        @param bounds: The boards that all areas in the expect_tree are bounded.
                       If None, ignore the bounds check.

        >>> f = FMap()
        >>> a = [{'name': 'FOO', 'offset': 100, 'size': '200'},
        ...      {'name': 'BAR', 'offset': 100, 'size': '50'},
        ...      {'name': 'ZEROSIZED', 'offset': 150, 'size': '0'},
        ...      {'name': 'OUTSIDE', 'offset': 50, 'size': '50'}]
        ...      {'name': 'OVERLAP', 'offset': 120, 'size': '50'},
        >>> f.check_areas(a, {'FOO': {}})
        True
        >>> f.check_areas(a, {'NOTEXISTED': {}})
        False
        >>> f.check_areas(a, {'ZEROSIZED': {}})
        False
        >>> f.check_areas(a, {'BAR': {}, 'OVERLAP': {}})
        False
        >>> f.check_areas(a, {'FOO': {}, 'BAR': {}})
        False
        >>> f.check_areas(a, {'FOO': {}, 'OUTSIDE': {}})
        True
        >>> f.check_areas(a, {'FOO': {'BAR': {}}})
        True
        >>> f.check_areas(a, {'FOO': {'OUTSIDE': {}}})
        False
        >>> f.check_areas(a, {'FOO': {'NOTEXISTED': {}}})
        False
        >>> f.check_areas(a, {'FOO': {'ZEROSIZED': {}}})
        False
        """

        succeed = True
        checked_regions = []
        for branch in expected_tree:
            area = next((a for a in areas if a['name'] == branch), None)
            if not area:
                logging.error("The area %s is not existed.", branch)
                succeed = False
                continue
            region = [int(area['offset'], 16),
                      int(area['offset'], 16) + int(area['size'], 16)]
            if int(area['size'], 16) == 0:
                logging.error("The area %s is zero-sized.", branch)
                succeed = False
            elif bounds and not self._is_bounded(region, bounds):
                logging.error("The region %s [%d, %d) is out of the bounds "
                              "[%d, %d).", branch, region[0], region[1],
                              bounds[0], bounds[1])
                succeed = False
            elif any(r for r in checked_regions if self._is_overlapping(
                    region, r)):
                logging.error("The area %s is overlapping others.", branch)
                succeed = False
            elif not self.check_areas(areas, expected_tree[branch], region):
                succeed = False
            checked_regions.append(region)
        return succeed


    def run_once(self):
        self.get_areas()

        for key in self._TARGET_AREA.keys():
            if (self._TARGET_AREA[key] and
                    not self.check_areas(self._TARGET_AREA[key],
                                         self._EXPECTED_FMAP_TREE[key])):
                raise error.TestFail("%s FMap is not qualified.", key)
        self.check_section()
