# Copyright 2017 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 collection of classes representing TCPC firmware blobs.
"""

import logging
import os
import subprocess


class ChipUtilsError(Exception):
    """Error in the chip_utils module."""



class generic_chip(object):

    """A chip we don't actually support."""

    chip_name = 'unknown'
    fw_name = None

    def __init__(self):
        self.fw_ver = None
        self.fw_file_name = None

    def set_fw_ver_from_string(self, version):
        """Sets version property from string."""
        self.fw_ver = int(version, 0)

    def set_from_file(self, file_name):
        """Sets chip params from file name.

        The typical firmware blob file name format is: <chip>_0x00.bin

        Args:
            file_name: Firmware blob file name.

        Raises:
            ValueError: Failed to decompose firmware file name.
        """

        basename = os.path.basename(file_name)
        if not basename.startswith(self.chip_name):
            raise ValueError('filename did not start with %s' % self.chip_name)
        fname = basename.split('.')[0]
        if '_' in fname:
            rev = fname.split('_')[-1]
            self.set_fw_ver_from_string(rev)
        else:
            logging.info('No fw ver found in filename %s', basename)
        self.fw_file_name = file_name


class ps8751(generic_chip):

    """The PS8751 TCPC chip."""

    chip_name = 'ps8751'
    fw_name = 'ps8751_a3'
    extension = '.bin'
    hash_extension = '.hash'
    cbfs_bin_name = fw_name + extension
    cbfs_hash_name = fw_name + hash_extension

    def fw_ver_from_hash(self, blob):
        """Return the firmware version encoded in the firmware hash."""

        return blob[1]

    def compute_hash_bytes(self):
        """Generates the firmware blob hash."""

        if self.fw_ver is None:
            raise ChipUtilsError('fw_ver not initialized')

        h = bytearray(2)
        h[0] = 0xa3
        h[1] = self.fw_ver
        return h


class anx3429(generic_chip):

    """The ANX3429 TCPC chip."""

    chip_name = 'anx3429'
    fw_name = 'anx3429_ocm'
    extension = '.bin'
    hash_extension = '.hash'
    cbfs_bin_name = fw_name + extension
    cbfs_hash_name = fw_name + hash_extension

    def fw_ver_from_hash(self, blob):
        """Return the firmware version encoded in the passed-in hash content."""
        return blob[0]

    def compute_hash_bytes(self):
        """Generates the firmware blob hash."""

        if self.fw_ver is None:
            raise ChipUtilsError('fw_ver not initialized')

        h = bytearray(1)
        h[0] = self.fw_ver
        return h


class ecrw(generic_chip):

    """Chrome EC RW portion."""

    chip_name = 'ecrw'
    fw_name = 'ecrw'
    extension = ''
    hash_extension = '.hash'
    cbfs_bin_name = fw_name
    cbfs_hash_name = fw_name + hash_extension

    def compute_hash_bytes(self):
        """Generates the firmware blob hash."""

        if self.fw_file_name is None:
            raise ChipUtilsError('fw_file_name not initialized')

        if not os.path.exists(self.fw_file_name):
            raise ChipUtilsError('%s does not exist' % self.fw_file_name)

        # openssl outputs the result to stdout
        cmd = 'openssl dgst -sha256 -binary %s' % self.fw_file_name
        result = subprocess.check_output(cmd, shell=True)
        return bytearray(result)


chip_id_map = {
        'ecrw': ecrw,
        '0x8751': ps8751,
        '0x3429': anx3429,
}
