# 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.

import logging
import os

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error

DEFAULT_MIN_GB = 16
# Allowable amount of bits eMMC vendor can use in firmware to support bad block
# replacement and metadata.
EMMC_VENDOR_ALLOWED_GB = 0.25
# Amount of data available for user data in device, the rest is left for
# over provisioning.
# Typically a SATA device will use 7% over provisioning [the difference
# between GB and GiB], but some eMMC device can use 9%.
# With Flash becoming more error prone as lithography shrinks, the trend
# is to increase over provisioning.
DEFAULT_USER_DENSITY = 0.9


class hardware_DiskSize(test.test):
    """
    Check that disk size is around 16GB at least.
    """

    version = 1

    def _is_emmc(self):
        path = os.path.join("/sys/class/block/", self._device,
                            "device", "type")
        if not os.path.exists(path):
            return False
        return utils.read_one_line(path) == 'MMC'


    @classmethod
    def _gib_to_gb(cls, gib):
        return float(gib) * (1 << 30) / (10 ** 9)

    def _compute_min_gb(self):
        """Computes minimum size allowed primary storage device.

        TODO(tbroch): Add computation of raw bytes in eMMC using 'Chip Specific
        Data' (CSD & EXT_CSD) defined by JEDEC JESD84-A44.pdf if possible.

        CSD :: /sys/class/block/<device>/device/csd
        EXT_CSD :: debugfs

        Algorithm should look something like this:
        CSD[C_SIZE] = 0xfff == eMMC > 2GB
        EXT_CSD[SEC_COUNT] = # of 512byte sectors

        Now for existing eMMC I've examined I do see the C_SIZE == 0xfff.
        Unfortunately the SEC_COUNT appears to have excluded the sectors
        reserved for metadata & repair.  Perhaps thats by design in which case
        there is no mechanism to determine the actual raw sectors.

        For now I use 0.25GB as an acceptable fudge.

        Returns:
            integer, in GB of minimum storage size.
        """

        min_gb = DEFAULT_MIN_GB
        if self._is_emmc():
            min_gb -= EMMC_VENDOR_ALLOWED_GB
        min_gb *= DEFAULT_USER_DENSITY
        return self._gib_to_gb(min_gb)


    def run_once(self):
        root_dev = utils.get_root_device()
        self._device = os.path.basename(root_dev)
        disk_size = utils.get_disk_size(root_dev)
        if not disk_size:
            raise error.TestError('Unable to determine main disk size')

        # Capacity of a hard disk is quoted with SI prefixes, incrementing by
        # powers of 1000, instead of powers of 1024.
        gb = float(disk_size) / (10 ** 9)

        self.write_perf_keyval({"gb_main_disk_size": gb})
        min_gb = self._compute_min_gb()
        logging.info("DiskSize: %.3f GB MinDiskSize: %.3f GB", gb, min_gb)
        if (gb < min_gb):
            raise error.TestError("DiskSize %.3f GB below minimum (%.3f GB)" \
                % (gb, min_gb))

