from .. import enums


class VmApiMixin:
    def vm_datacenter_get(self, *, vdc_id, **kwargs):
        """
        This method allows you to retrieve a datacenter's information by vdc_id.

        :param int vdc_id: VM Datacenter identifier.

        :return: On success, returns an object with the following properties:
        :rtype: dict

        **Properties**

        vdc_agent_hostname
            Agent hostname/IP address.
        vdc_agent_password
            Agent password.
        vdc_agent_username
            Agent username.
        vdc_date_added
            Timestamp of when VDC was added to NETLAB+.
        vdc_date_tested
            Timestamp of when VDC was last tested.
        vdc_last_test_status
            Status of last VDC test.
        vdc_id
            VM Datacenter identifier.
        vdc_name
            VM Datacenter name.
        vdt_type
            VM Datacenter type.
        vdt_name
            VM Datacenter type name.
        """

        method = "vm.datacenter.get"
        return self.call(method, vdc_id=vdc_id, **kwargs)

    def vm_datacenter_find(self, *, vdc_name, **kwargs):
        """
        This method allows you to find a datacenter's **vdc_id** by the datacenter name.

        :param str vdc_name: VM Datacenter name.

        :return: On success, returns vdc_id.
        :rtype: int
        """

        method = "vm.datacenter.get"
        datacenter = self.call(method, vdc_name=vdc_name, **kwargs)
        return datacenter['vdc_id']

    def vm_datacenter_list(self, **kwargs):
        """
        This method allows you to retrieve all datacenters' information.

        :return: A list of objects with the following properties:
        :rtype: list

        **Properties**

        vdc_agent_hostname
            Agent hostname/IP address.
        vdc_agent_password
            Agent password.
        vdc_agent_username
            Agent username.
        vdc_date_added
            Timestamp of when VDC was added to NETLAB+.
        vdc_date_tested
            Timestamp of when VDC was last tested.
        vdc_last_test_status
            Status of last VDC test.
        vdc_id
            VM Datacenter identifier.
        vdc_name
            VM Datacenter name.
        vdt_type
            VM Datacenter type.
        vdt_name
            VM Datacenter type name.
        """

        method = "vm.datacenter.list"
        return self.call(method, **kwargs)

    def vm_datacenter_test(self, *, vdc_id, **kwargs):
        """
        This method allows you to call a task to test communication to datacenter.

        :param int vdc_id: VM Datacenter identifier.

        :return: On success returns 'PASSED', otherwise returns 'FAILED'.
        :rtype: 'PASSED' or 'FAILED'
        """

        method = "vm.datacenter.test.task"
        return self.call(method, vdc_id=vdc_id, **kwargs)

    def vm_host_get(self, *, vh_id, **kwargs):
        """
        This method allows you to retrieve a virtual host information.

        :param int vh_id: Virtual host identifier.

        :return: On success, returns an object with the following properties:
        :rtype: dict

        **Properties**

        vdc_id
            Agent hostname/IP address.
        vdc_name
            VM Datacenter name.
        vdt_type
            VM Datacenter type.
        vdt_name
            VM Datacenter type name.
        vh_bios_date
            Timestamp of BIOS creation date.
        vh_bios_version
            BIOS version installed.
        vh_com_path
            Virtual host communication path.
        vh_cpu_cores
            Total count of CPU cores on virtual host.
        vh_cpu_count
            Total count of physical CPUs on virtual host.
        vh_cpu_mhz
            Speed in MHz of CPU.
        vh_cpu_model
            CPU model identification.
        vh_cpu_threads
            Number of threads CPUs can handle.
        vh_date_added
            Timestamp of virtual host added to NETLAB+.
        vh_date_modified
            Timestamp of virtual host information has been modified.
        vh_date_tested
            Timestamp of virtual host test communication.
        vh_id
            Virtual host identifier.
        vh_inside_ipv4_addr
            Inside interface ipv4 address.
        vh_inside_vswitch_0
            Virtual host inside vSwitch.
        vh_last_test_status
            Status of last virtual host test communication.
        vh_memory_mb
            Total RAM in MB of virtual host.
        vh_name
            Virtual host hostname.
        vh_online
            Virtual host is online.
        vh_os_build
            Operating system build number.
        vh_os_description
            Operating system description.
        vh_os_name
            Operating system name.
        vh_os_type
            Operating system type.
        vh_os_vendor
            Operating system vender.
        vh_os_version
            Operating system version.
        vh_outside_ipv4_addr
            Outside interface ipv4 address.
        vh_pra_enabled
            Proactive resource awareness is enabled.
        vh_pra_max_cpu
            Max number of CPUs for PRA.
        vh_pra_max_mem_mb
            Max amount of RAM in MB for PRA.
        vh_pra_max_vm
            Max amount of virtual machines for PRA.
        vh_sys_model
            System model.
        vh_sys_service_tag
            System service tag.
        vh_sys_vendor
            System vendor.
        vh_uuid
            Virtual host unique global identifier.
        """

        method = "vm.host.get"
        return self.call(method, vh_id=vh_id, **kwargs)

    def vm_host_list(self, *, vdc_id=0, **kwargs):
        """
        This method allows you to retrieve a list of virtual hosts information.

        :param str vdc_id: VM Datacenter identifier. If not specified, will return from all datacenters.

        :return: Returns a list of objects with the following properties:
        :rtype: dict

        **Properties**

        vdc_id
            Agent hostname/IP address.
        vdc_name
            VM Datacenter name.
        vdt_type
            VM Datacenter type.
        vdt_name
            VM Datacenter type name.
        vh_bios_date
            Timestamp of BIOS creation date.
        vh_bios_version
            BIOS version installed.
        vh_com_path
            Virtual host communication path.
        vh_cpu_cores
            Total count of CPU cores on virtual host.
        vh_cpu_count
            Total count of physical CPUs on virtual host.
        vh_cpu_mhz
            Speed in MHz of CPU.
        vh_cpu_model
            CPU model identification.
        vh_cpu_threads
            Number of threads CPUs can handle.
        vh_date_added
            Timestamp of virtual host added to NETLAB+.
        vh_date_modified
            Timestamp of virtual host information has been modified.
        vh_date_tested
            Timestamp of virtual host test communication.
        vh_id
            Virtual host identifier.
        vh_inside_ipv4_addr
            Inside interface ipv4 address.
        vh_inside_vswitch_0
            Virtual host inside vSwitch.
        vh_last_test_status
            Status of last virtual host test communication.
        vh_memory_mb
            Total RAM in MB of virtual host.
        vh_name
            Virtual host hostname.
        vh_online
            Virtual host is online.
        vh_os_build
            Operating system build number.
        vh_os_description
            Operating system description.
        vh_os_name
            Operating system name.
        vh_os_type
            Operating system type.
        vh_os_vendor
            Operating system vender.
        vh_os_version
            Operating system version.
        vh_outside_ipv4_addr
            Outside interface ipv4 address.
        vh_pra_enabled
            Proactive resource awareness is enabled.
        vh_pra_max_cpu
            Max number of CPUs for PRA.
        vh_pra_max_mem_mb
            Max amount of RAM in MB for PRA.
        vh_pra_max_vm
            Max amount of virtual machines for PRA.
        vh_sys_model
            System model.
        vh_sys_service_tag
            System service tag.
        vh_sys_vendor
            System vendor.
        vh_uuid
            Virtual host unique global identifier.
        """

        method = "vm.host.list"
        return self.call(method, vdc_id=vdc_id, **kwargs)

    def vm_inventory_add(self, *, vdc_id, vm_uuid, vm_name, vm_alloc_mem_mb, vm_alloc_cpu_n, vhg_id=None, vh_id=None,
                         vm_role=enums.VirtualMachineRole.NORMAL, vm_comments=None, vm_vendor_os_id=None, **kwargs):
        """
        Add virtual machines to NETLAB+ inventory.

        :param int vdc_id: VM Datacenter identifier.
        :param int vhg_id: Virtual host group identifier.
        :param int vh_id: Virtual host identifier.
        :param str vm_uuid: Virtual machine unique identifier.
        :param str vm_name: Virtual machine name.
        :param str vm_path: Virtual machine path on datastore.
        :param netlab.enums.VirtualMachineRole vm_role Virtual machine role in NETLAB+ inventory.
        :param int vm_alloc_mem_mb: Total amount of allocated RAM.
        :param int vm_alloc_cpu_n: Total amount of allocated CPUs.
        :param str vm_comments: Virtual machine comments from VMX.
        :param str vm_vendor_os_id: Vendor operating system identifier.
        :param str vm_vendor_os_name: Vendor operating system name.
        :param str vm_netlab_os_id: NETLAB+ match to vm_vendor_os_id.
        :param int vm_parent_id: Virtual machine parent identifier, if VM is a link clone.
        :param str vm_parent_snapname: Virtual machine parent snapname, if VM is a link clone.

        :return: Returns a list of object with the following properties:
        :rtype: list[dict]

        **properties**

        vm_id
            Virtual machine identifier.
        """

        method = 'vm.inventory.add'
        return self.call(method, vdc_id=vdc_id, vm_uuid=vm_uuid, vm_name=vm_name, vm_alloc_mem_mb=vm_alloc_mem_mb,
                         vm_alloc_cpu_n=vm_alloc_cpu_n, vhg_id=vhg_id, vh_id=vh_id, vm_role=vm_role,
                         vm_comments=vm_comments, vm_vendor_os_id=vm_vendor_os_id, **kwargs)

    def vm_inventory_get(self, *, vm_id, **kwargs):
        """
        This method allows you to retrieve one or more virtual machines from NETLAB+ inventory.

        :param int vm_id: Virtual machine identifier.

        :return: Returns an object with the following properties:
        :rtype: dict

        **Properties**

        pc_id
            Remote pc identifier.
        pc_label
            Remote pc label.
        pc_os_id
            NETLAB+ operating system identifier.
        pc_os_name
            NETLAB+ operating system name.
        pc_pod_id
            If attached to a pod, pod identifier.
        pc_vm_id
            Virtual machine identifier.
        pod_name
            Pod name.
        vdc_id
            Virtual datacenter identifier.
        vdc_name
            Virtual datacenter name.
        vh_id
            Virtual host identifier.
        vh_name
            Virtual host name.
        vhg_id
            Virtual host group identifier.
        vhg_name
            Virtual host group name.
        vm_alloc_cpu_n
            Total amount of allocated CPUs.
        vm_alloc_mem_mb
            Total amount of allocated RAM.
        vm_child_count
            Total count of children VMs.
        vm_comments
            Virtual machine comments from VMX.
        vm_date_added
            Timestamp of virtual machine added to NETLAB+ inventory.
        vm_id
            Virtual machine identifier.
        vm_name
            Virtual machine name.
        vm_netlab_os_id
            NETLAB+ match to vm_vendor_os_id.
        vm_parent_id
            Virtual machine parent identifier, if VM is a link clone.
        vm_parent_name
            Virtual machine parent name.
        vm_parent_role
            Parent virtual machine role.
        vm_parent_snapname
            Virtual machine parent snapname, if VM is a link clone.
        vm_path
            Virtual machine path on datastore.
        vm_power_state
            Virtual machine power state.
        vm_role
            Virtual machine role in NETLAB+ inventory.
        vm_snapshot
            Virtual machine snapshot name.
        vm_uuid
            Virtual machine unique identifier.
        vm_vendor_os_id
            Vendor operating system identifier.
        vm_vendor_os_name
            Vendor operating system name.

        """
        method = "vm.inventory.get"
        return self.call(method, vm_id=vm_id, **kwargs)

    def vm_inventory_list(self, *, vdc_id=None, roles=None, attached=None, **kwargs):
        """
        This method allows you to list the virtual machines from NETLAB+ inventory.

        :param int vdc_id: VM Datacenter identifier.
        :param list roles: Filter by specified roles.
        :param int attached: List virtual machines attached to a pod.


        :return: Returns an object with the following properties:
        :rtype: dict

        **Properties**

        pc_id
            Remote pc identifier.
        pc_label
            Remote pc label.
        pc_os_id
            NETLAB+ operating system identifier.
        pc_os_name
            NETLAB+ operating system name.
        pc_pod_id
            If attached to a pod, pod identifier.
        pc_vm_id
            Virtual machine identifier.
        pod_name
            Pod name.
        vdc_id
            Virtual datacenter identifier.
        vdc_name
            Virtual datacenter name.
        vh_id
            Virtual host identifier.
        vh_name
            Virtual host name.
        vhg_id
            Virtual host group identifier.
        vhg_name
            Virtual host group name.
        vm_alloc_cpu_n
            Total amount of allocated CPUs.
        vm_alloc_mem_mb
            Total amount of allocated RAM.
        vm_child_count
            Total count of children VMs.
        vm_comments
            Virtual machine comments from VMX.
        vm_date_added
            Timestamp of virtual machine added to NETLAB+ inventory.
        vm_id
            Virtual machine identifier.
        vm_name
            Virtual machine name.
        vm_netlab_os_id
            NETLAB+ match to vm_vendor_os_id.
        vm_parent_id
            Virtual machine parent identifier, if VM is a link clone.
        vm_parent_name
            Virtual machine parent name.
        vm_parent_role
            Parent virtual machine role.
        vm_parent_snapname
            Virtual machine parent snapname, if VM is a link clone.
        vm_path
            Virtual machine path on datastore.
        vm_power_state
            Virtual machine power state.
        vm_role
            Virtual machine role in NETLAB+ inventory.
        vm_snapshot
            Virtual machine snapshot name.
        vm_uuid
            Virtual machine unique identifier.
        vm_vendor_os_id
            Vendor operating system identifier.
        vm_vendor_os_name
            Vendor operating system name.
        """
        method = "vm.inventory.get"
        params = {}

        if vdc_id:
            params['vdc_id'] = vdc_id
        if roles:
            params['roles'] = roles
        if attached is not None:
            params['attached'] = attached

        params.update(kwargs)
        return self.call(method, **params)

    def vm_snapshot_add(self, *, vm_id=None, pc_id=None, snapshot_name, dump_memory=False, sync=False,
                        description=None, **kwargs):
        """
        Method to call a task to add snapshot to virtual machine.

        :param int vm_id: Virtual datacenter identifier.
        :param int pc_id: Remote pc identifier.
        :param str snapshot_name: Name of snapshot to take.
        :param bool dump_memory: Dump memory files.
        :param bool sync: Sync files.
        :param str description: Snapshot description.

        :return: The snapshot completed successfully.
        :rtype: 'OK'
        """

        method = "vm.snapshot.add.task"
        return self.call(method, vm_id=vm_id, pc_id=pc_id, snapshot_name=snapshot_name, dump_memory=dump_memory,
                         sync=sync, description=description, **kwargs)

    def vm_snapshot_edit(self, *, vm_id=None, pc_id=None, snapshot_id=None, new_snapshot_name=None,
                         new_snapshot_description=None, **kwargs):
        """
        Method to call a task to edit a snapshot.

        :param int vm_id: Virtual datacenter identifier.
        :param int pc_id: Remote pc identifier.
        :param int snapshot_id: Snapshot identifier.
        :param int new_snapshot_name: New name of snapshot to take.
        :param str new_snapshot_description: New description of snapshot.

        :return: The edit completed successfully.
        :rtype: 'OK'
        """
        method = "vm.snapshot.edit.task"
        return self.call(method, vm_id=vm_id, pc_id=pc_id, snapshot_id=snapshot_id,
                         new_snapshot_name=new_snapshot_name, new_snapshot_description=new_snapshot_description,
                         **kwargs)

    def vm_snapshot_get_list(self, *, vm_id=None, pc_id=None, **kwargs):
        """
        Method to call a task to retrieve a list of snapshots.

        :param int vm_id: Virtual datacenter identifier.
        :param int pc_id: Remote pc identifier.

        :return: Returns a dict with the following properties:
        :rtype: dict

        **Properties**
        current_snapshot
            The current snapshot. See *Snapshot properties* for more info.
        snapshot_list
            A list of all snapshots. See *Snapshot properties* for more info.

        **Snapshot properties**
        power_state
            The state of the snapshot. :py:class:`PowerState`
        name
            The snapshot name.
        description
            The snapshot description.
        parent_id
            The id of the snapshot parent.
        id
            The snapshot id.
        mo_ref
            The unique identifier of the managed object in vSphere.
        """
        method = "vm.snapshot.get.list.task"
        return self.call(method, vm_id=vm_id, pc_id=pc_id, **kwargs)

    def vm_snapshot_get_tree(self, *, vm_id=None, pc_id=None, **kwargs):
        """
        Method to call a task to retrieve snapshot tree.

        :param int vm_id: Virtual datacenter identifier.
        :param int pc_id: Remote pc identifier.

        :return: Returns a dict with the following properties:
        :rtype: dict

        **Properties**
        current_snapshot
            The current snapshot. See *Snapshot properties* for more info.
        snapshot_list
            A list of all snapshots. See *Snapshot properties* for more info.

        **Snapshot properties**
        power_state
            The state of the snapshot. :py:class:`PowerState`
        name
            The snapshot name.
        description
            The snapshot description.
        id
            The snapshot id.
        mo_ref
            The unique identifier of the managed object in vSphere.
        """
        method = "vm.snapshot.get.tree.task"
        return self.call(method, vm_id=vm_id, pc_id=pc_id, **kwargs)

    def vm_snapshot_remove(self, *, vm_id=None, pc_id=None, snapshot_name=None, snapshot_id=None, remove_children=None,
                           remove_all_snapshots=None, **kwargs):
        """
        Method to call a task to remove snapshot from virtual machine.

        :param int vm_id: Virtual datacenter identifier.
        :param int pc_id: Remote pc identifier.
        :param str snapshot_name: Name of snapshot to take.
        :param int snapshot_id: Snapshot identifier.
        :param bool remove_children: Remove children snapshots.
        :param bool remove_all_snapshots: Remove all snapshots of virtual machine.

        :return: The removal completed successfully.
        :rtype: 'OK'
        """
        method = "vm.snapshot.remove.task"
        return self.call(
            method, vm_id=vm_id, pc_id=pc_id, snapshot_name=snapshot_name, snapshot_id=snapshot_id,
            remove_children=remove_children, remove_all_snapshots=remove_all_snapshots, **kwargs)

    def vm_snapshot_revert(self, *, vm_id=None, pc_id=None, snapshot_name=None, snapshot_id=None, **kwargs):
        """
        Method to call a task to revert to snapshot from virtual machine.

        :param int vm_id: Virtual datacenter identifier.
        :param int pc_id: Remote pc identifier.
        :param str snapshot_name: Name of snapshot to take.
        :param int snapshot_id: Snapshot identifier.

        :return: The revert completed successfully.
        :rtype: 'OK'
        """
        method = "vm.snapshot.revert.task"
        return self.call(
            method, vm_id=vm_id, pc_id=pc_id, snapshot_name=snapshot_name, snapshot_id=snapshot_id, **kwargs)
