# Copyright 2019-2020 VMware, Inc.
# All rights reserved. -- VMware Confidential
"""
This module performs precheck relating to adding disk during B2b
"""

import logging
import traceback
from l10n import msgMetadata as _T, localizedString as _
from patch_errors import UserError
from pyVmomi import vim  # pylint: disable=E0401,E0611

logger = logging.getLogger(__name__)


def verify_required_scsi_slots_available(vm_obj, no_of_disks_to_add):
    """
    This method checks required scsi slots are available for adding new disks
    are not. if the slots are available we return True else we throw exception
    :param no_of_disks_to_add:No of disks we are going to add during patching
    """
    try:
        # Here for each scsi controller available, we check the no of slots
        # and add them. if count of slots available is equal to the required one
        # we return otherwise we fail stating the no slots available
        total_available_slots = 0
        for dev in vm_obj.config.hardware.device:
            if isinstance(dev, vim.vm.device.VirtualSCSIController):
                count = 15 - len(dev.device)
                total_available_slots = count + total_available_slots

        if total_available_slots >= no_of_disks_to_add:
            logger.info("Required slots are: %s. Available slots are: "
                        "%s. ", no_of_disks_to_add,
                        total_available_slots)
            logger.info("Precheck for the SCSI slots passed.")
            return

        # here am raising the alaram stating that no scsi slots are available
        cause = _(_T("sufficient.scsci.slots.not.available.on.vm.error",
                     "Not enough SCSI slots available to add new disks.  "
                     "Need %s slots.  Only %s is currently available."),
                  [no_of_disks_to_add, total_available_slots])

        resolution = _(
            _T("sufficient.scsci.slots.not.available.on.vm.description",
               "Not enough SCSI slots available to add new disks.Need %s slots. Only %s is currently available. "
               "Ensure that the required number of SCSI slots are available."),
            [no_of_disks_to_add, total_available_slots])
        raise UserError(cause=cause, resolution=resolution)
    except UserError as ue:
        raise ue
    except Exception:
        cause = _(_T('precheck.validate.scsci.slots.failed.error',
                     'Precheck  for SCSI slots failed due to %s.'),
                  traceback.format_exc())
        resolution = _(_T('precheck.validate.scsci.slots.failed.description',
                          'Precheck for SCSI slots failed due to %s. Correct '
                          'the issue and retry.'), traceback.format_exc())
        raise UserError(cause=cause, resolution=resolution)


def disk_addition_precheck(vm_obj, no_of_disks_to_add):
    """
    This method is wrapper which calls two methods which confirms
     disk addition can be done or not during b2b
    :param vm_obj: VM object to which new disk is being added
    :param disk_size_needed: disk size needed from the datastore
    :param no_of_disks_to_add: No of disks to be added to the disk.
    :return: True if the required size is available else  exception
    """
    # verify_storage_requirement(vm_obj, disk_size_needed)
    verify_required_scsi_slots_available(vm_obj, no_of_disks_to_add)
    return True
