from unittest import TestCase
from mock import Mock, mock
from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim

from cloudshell.cp.vcenter.commands.vm_details import VmDetailsCommand
from cloudshell.cp.vcenter.common.vcenter.task_waiter import SynchronousTaskWaiter
from cloudshell.cp.vcenter.common.vcenter.vmomi_service import pyVmomiService
from cloudshell.cp.vcenter.network.vnic.vnic_service import VNicService
from cloudshell.cp.vcenter.vm.ip_manager import VMIPManager
from cloudshell.cp.core.models import  VmDetailsProperty,VmDetailsData,VmDetailsNetworkInterface
from cloudshell.tests.utils.testing_credentials import TestCredentials
from cloudshell.cp.vcenter.vm.vm_details_provider import VmDetailsProvider,VmDetailsData

class TestVmDetailsCommand(TestCase):

    @mock.patch('cloudshell.tests.test_commands.test_vm_details.VNicService.get_network_by_device')
    def test(self, get_network_by_device):
        # ARRANGE
        network = Mock()
        network.name = 'Net1'
        network.config.defaultPortConfig.vlan.vlanId = '65'
        get_network_by_device.return_value = network
        vm = self.mock_vm()
        si = Mock()
        pyvmomi_service = Mock()
        pyvmomi_service.find_by_uuid = Mock(return_value=vm)
        param = Mock()
        param.name = 'ip_regex'
        param.value = '.*'
        request = Mock()
        request.deployedAppJson.name = 'App1'
        request.deployedAppJson.vmdetails.vmCustomParams = [param]
        request.appRequestJson.deploymentService.model = 'vCenter Clone VM From VM'
        request.appRequestJson.deploymentService.attributes = [Mock()]
        resource_context = Mock()
        resource_context.attributes = {'Reserved Networks': 'Net1;B'}
        cancellation_context = Mock(is_cancelled=False)
        ip_manager = VMIPManager()
        vm_details_provider = VmDetailsProvider(pyvmomi_service, ip_manager)
        # ACT
        command = VmDetailsCommand(pyvmomi_service, vm_details_provider)
        datas = command.get_vm_details(
            si=si,
            logger=Mock(),
            resource_context=resource_context,
            requests=[request],
            cancellation_context=cancellation_context)
        # ASSERT
        self.assertEqual(len(datas), 1)
        vm_details = datas[0]
        if isinstance(vm_details,VmDetailsData):
            pass
        self.assertEqual(vm_details.appName, 'App1')
        self.assertEqual(vm_details.errorMessage, '')
        self.assertEqual(len(vm_details.vmInstanceData), 6)

        self.assertEqual(len(vm_details.vmNetworkData), 1)
        nic = vm_details.vmNetworkData[0]

        if isinstance(nic,VmDetailsNetworkInterface):
            pass

        self.assertEqual(nic.interfaceId, 'Mac1')
        self.assertEqual(nic.isPredefined, True)
        self.assertEqual(nic.isPrimary, True)
        self.assertEqual(nic.networkId, '65')

        self.assertEqual(len(nic.networkData), 4)

        self.assertEqual(self._get_value(nic.networkData, 'IP') , '1.2.3.4')
        self.assertEqual(self._get_value(nic.networkData, 'MAC Address') , 'Mac1')
        self.assertEqual(self._get_value(nic.networkData, 'Network Adapter') , 'NetDeviceLabel')
        self.assertEqual(self._get_value(nic.networkData, 'Port Group Name') , 'Net1')


    def mock_vm(self):
        vm = Mock()
        vm.summary.config.memorySizeMB = 2 * 1024
        disk = vim.vm.device.VirtualDisk()
        disk.capacityInKB = 20 * 1024 * 1024
        nic = vim.vm.device.VirtualEthernetCard()
        nic.key = 2
        nic.deviceInfo = vim.Description()
        nic.deviceInfo.label = 'NetDeviceLabel'
        nic.macAddress = 'Mac1'
        vm.config.hardware.device = [disk, nic]
        vm.summary.config.numCpu = 4
        vm.summary.config.guestFullName = 'Centos'
        node = Mock()
        node.snapshot = Mock()
        node.name = 'Snap1'
        vm.snapshot.rootSnapshotList = [node]  # [Mock(snapshot=snapshot,name=Mock(return_value='Snap1'))]
        vm.snapshot.currentSnapshot = node.snapshot
        vm.guest.net = [Mock(deviceConfigId='2', ipAddress=['1.2.3.4'])]
        vm.guest.ipAddress = '1.2.3.4'
        return vm

    def _get_value(self, data, key):
        for item in data:
            if item.key == key:
                return item.value
        return None

    # def integration(self):
    #     credentials = TestCredentials()
    #     py_vmomi_service = pyVmomiService(connect=SmartConnect, disconnect=Disconnect,
    #                                       task_waiter=SynchronousTaskWaiter())
    #     si = py_vmomi_service.connect(credentials.host, credentials.username, credentials.password)
    # 
    #     vm_details_provider = VmDetailsProvider(py_vmomi_service,VMIPManager())
    #     cancel = Mock()
    #     cancel.is_cancelled = False
    #     logger = Mock()
    #     resource_context = Mock()
    #     resource_context.attributes = {'Reserved Networks': 'A'}
    #     requests = [Mock()]
    #     requests[0].deployedAppJson = Mock()
    #     requests[0].deployedAppJson.name = 'SomeApp'
    #     requests[0].deployedAppJson.vmdetails = Mock()
    #     requests[0].deployedAppJson.vmdetails.uid = '423283e4-0003-6e04-07bb-7e4c3ebcf993'
    #     requests[0].deployedAppJson.vmdetails.vmCustomParams = []
    #     requests[0].appRequestJson = Mock()
    #     requests[0].appRequestJson.deploymentService = Mock()
    #     requests[0].appRequestJson.deploymentService.model = 'vCenter Clone VM From VM'
    #     requests[0].appRequestJson.deploymentService.attributes = [Mock()]
    #
    #     vm = py_vmomi_service.find_by_uuid(si, '423283e4-0003-6e04-07bb-7e4c3ebcf993')
    #
    #     cmd = VmDetailsCommand(py_vmomi_service, vm_details_provider)
    #     d = cmd.get_vm_details(si, logger, resource_context, requests, cancel)
    #     pass