# Copyright (c) 2010 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.
"""A module containing TPM handler class used by SAFT."""

FW_NV_ADDRESS = 0x1007
KERNEL_NV_ADDRESS = 0x1008


class TpmError(Exception):
    """An object to represent TPM errors"""
    pass


class TpmNvRam(object):
    """An object representing TPM NvRam.

    @ivar addr: a number, NvRAm address in TPM.
    @ivar size: a number, count of bites in this NvRam section.
    @ivar os_if: an instance of the OS interface (os_interface or a mock object)
    @ivar version_offset: - a number, offset into the NvRam contents where the
        the versions are stored. The total version field size is 4 bytes, the
        first two bytes are the body version, the second two bytes are the key
        version. Numbers are stored in little endian format.
    @ivar pattern: optional, a tuple of two elements, the first element is the
       offset of the pattern expected to be present in the NvRam, and the
       second element is an array of bytes the pattern must match.
    @ivar contents: an array of bytes, the contents of the NvRam.
    @type os_if: autotest_lib.client.cros.faft.utils.os_interface.OSInterface
    """

    def __init__(self, os_if, addr, size, version_offset, data_pattern=None):
        self.os_if = os_if
        self.addr = addr
        self.size = size
        self.version_offset = version_offset
        self.pattern = data_pattern
        self.contents = []

    def init(self):
        """Initialize the object, loading tpm nvram information from the device.
        """
        cmd = 'tpmc read 0x%x 0x%x' % (self.addr, self.size)
        output = self.os_if.run_shell_command_get_output(cmd)
        if not output:
            raise TpmError('Failed to read Nvram')
        nvram_data = output[0].split()
        self.contents = [int(x, 16) for x in nvram_data]
        if self.pattern:
            pattern_offset = self.pattern[0]
            pattern_data = self.pattern[1]
            contents_pattern = self.contents[pattern_offset:pattern_offset +
                                             len(pattern_data)]
            if contents_pattern != pattern_data:
                raise TpmError('Nvram pattern does not match')

    def get_body_version(self):
        return self.contents[self.version_offset + 1] * 256 + self.contents[
                self.version_offset]

    def get_key_version(self):
        return self.contents[self.version_offset + 3] * 256 + self.contents[
                self.version_offset + 2]


class TpmNvRamOptions(object):
    """An object representing a number of potential TPM NvRam objects.

    @ivar nvrams: A list of TpmNvRam objects. The first TpmNvRam that
        successfully initializes is selected and used so more specific
        selectors should be listed earlier.
    """

    def __init__(self, nvrams):
        self._nvrams = nvrams
        self._valid_nvram = None

    def init(self):
        """Selects a valid TpmNvRam and initializes it."""
        for nvram in self._nvrams:
            try:
                nvram.init()
            except TpmError:
                continue
            else:
                self._valid_nvram = nvram
                break
        else:
            raise TpmError('No Nvram pattern matched')

    def get_body_version(self):
        return self._valid_nvram.get_body_version()

    def get_key_version(self):
        return self._valid_nvram.get_key_version()


class TpmHandler(object):
    """An object to control TPM device's NVRAM.

    @ivar os_if: an instance of the OS interface (os_interface or a mock object)
    @ivar nvrams: A dictionary where the keys are nvram names, and the values
          are instances of TpmNvRam objects, providing access to the
          appropriate TPM NvRam sections.
    @ivar tpm_version: Either "1.2" or "2.0".
    @type os_if: autotest_lib.client.cros.faft.utils.os_interface.OSInterface
    """

    def __init__(self, os_if):
        self.os_if = os_if
        self.nvrams = {
                'kernel':
                TpmNvRamOptions([
                        TpmNvRam(
                                self.os_if,
                                addr=KERNEL_NV_ADDRESS,
                                size=13,
                                version_offset=5,
                                data_pattern=(1, [0x4c, 0x57, 0x52, 0x47])),
                        TpmNvRam(
                                self.os_if,
                                addr=KERNEL_NV_ADDRESS,
                                size=0x28,
                                version_offset=4,
                                data_pattern=(0, [0x10, 0x28])),
                ]),
                'bios':
                TpmNvRam(
                        self.os_if,
                        addr=FW_NV_ADDRESS,
                        size=10,
                        version_offset=2)
        }
        self.tpm_version = None
        self.trunksd_started = False
        self.tcsd_started = False
        self.initialized = False

    def init(self):
        """Initialize the values of the nvram sections.

        This is separate from object creation so it can be done only when a test
        actually uses it.
        """
        self.stop_daemon()
        for nvram in self.nvrams.itervalues():
            nvram.init()
        self.restart_daemon()
        self.initialized = True

    def get_fw_version(self):
        return self.nvrams['bios'].get_body_version()

    def get_fw_key_version(self):
        return self.nvrams['bios'].get_key_version()

    def get_kernel_version(self):
        return self.nvrams['kernel'].get_body_version()

    def get_kernel_key_version(self):
        return self.nvrams['kernel'].get_key_version()

    def get_tpm_version(self):
        if self.tpm_version is None:
            self.tpm_version = self.os_if.run_shell_command_get_output(
                    'tpmc tpmver')[0]
        return self.tpm_version

    def stop_daemon(self):
        """Stop TPM related daemon."""
        if self.trunksd_started or self.tcsd_started:
            raise TpmError('Called stop_daemon() before')

        cmd = 'initctl status tcsd || initctl status trunksd'
        status = self.os_if.run_shell_command_get_output(cmd) or ['']
        # Expected status is like ['trunksd start/running, process 2375']
        self.trunksd_started = status[0].startswith('trunksd start/running')
        if self.trunksd_started:
            self.os_if.run_shell_command('stop trunksd')
        else:
            self.tcsd_started = status[0].startswith('tcsd start/running')
            if self.tcsd_started:
                self.os_if.run_shell_command('stop tcsd')

    def restart_daemon(self):
        """Restart TPM related daemon which was stopped by stop_daemon()."""
        if self.trunksd_started:
            self.os_if.run_shell_command('start trunksd')
            self.trunksd_started = False
        elif self.tcsd_started:
            self.os_if.run_shell_command('start tcsd')
            self.tcsd_started = False
