#!/usr/bin/python
#
# Copyright (c) 2019 Zim Kalinowski, <zikalino@microsoft.com>
#
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


DOCUMENTATION = '''
---
module: azure_rm_virtualmachinescalesetinstance_info
version_added: "0.1.2"
short_description: Get Azure Virtual Machine Scale Set Instance facts
description:
    - Get facts of Azure Virtual Machine Scale Set VMs.

options:
    resource_group:
        description:
            - The name of the resource group.
        required: True
        type: str
    vmss_name:
        description:
            - The name of the VM scale set.
        required: True
        type: str
    instance_id:
        description:
            - The instance ID of the virtual machine.
        type: str
    tags:
        description:
            - Limit results by providing a list of tags. Format tags as 'key' or 'key:value'.
        type: list
        elements: str

extends_documentation_fragment:
    - azure.azcollection.azure

author:
    - Zim Kalinowski (@zikalino)

'''

EXAMPLES = '''
- name: List VM instances in Virtual Machine ScaleSet
  azure_rm_virtualmachinescalesetinstance_info:
    resource_group: myResourceGroup
    vmss_name: myVMSS
'''

RETURN = '''
instances:
    description:
        - A list of dictionaries containing facts for Virtual Machine Scale Set VM.
    returned: always
    type: complex
    contains:
        id:
            description:
                - Resource ID.
            returned: always
            type: str
            sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachineScaleSets/my
                     VMSS/virtualMachines/2"
        tags:
            description:
                - Resource tags.
            returned: always
            type: dict
            sample: { 'tag1': 'abc' }
        instance_id:
            description:
                - Virtual Machine instance ID.
            returned: always
            type: str
            sample: 0
        name:
            description:
                - Virtual Machine name.
            returned: always
            type: str
            sample: myVMSS_2
        latest_model:
            description:
                - Whether applied latest model.
            returned: always
            type: bool
            sample: True
        provisioning_state:
            description:
                - Provisioning state of the Virtual Machine.
            returned: always
            type: str
            sample: Succeeded
        power_state:
            description:
                - Provisioning state of the Virtual Machine's power.
            returned: always
            type: str
            sample: running
        vm_id:
            description:
                - Virtual Machine ID
            returned: always
            type: str
            sample: 94a141a9-4530-46ac-b151-2c7ff09aa823
        image_reference:
            description:
                - Image reference
            returned: always
            type: dict
            sample: { "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myGroup/providers/Microsoft.Compute/galleries/
                        myGallery/images/myImage/versions/10.1.3"}
'''

from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase

try:
    from azure.mgmt.compute import ComputeManagementClient
    from azure.core.exceptions import ResourceNotFoundError
except ImportError:
    # This is handled in azure_rm_common
    pass


class AzureRMVirtualMachineScaleSetVMInfo(AzureRMModuleBase):
    def __init__(self):
        # define user inputs into argument
        self.module_arg_spec = dict(
            resource_group=dict(
                type='str',
                required=True
            ),
            vmss_name=dict(
                type='str',
                required=True
            ),
            instance_id=dict(
                type='str'
            ),
            tags=dict(
                type='list',
                elements='str'
            )
        )
        # store the results of the module operation
        self.results = dict(
            changed=False
        )
        self.mgmt_client = None
        self.resource_group = None
        self.vmss_name = None
        self.instance_id = None
        self.tags = None
        super(AzureRMVirtualMachineScaleSetVMInfo, self).__init__(self.module_arg_spec, supports_check_mode=True, supports_tags=False, facts_module=True)

    def exec_module(self, **kwargs):
        is_old_facts = self.module._name == 'azure_rm_virtualmachinescalesetinstance_facts'
        if is_old_facts:
            self.module.deprecate("The 'azure_rm_virtualmachinescalesetinstance_facts' module has been renamed to" +
                                  " 'azure_rm_virtualmachinescalesetinstance_info'",
                                  version=(2.9, ))

        for key in self.module_arg_spec:
            setattr(self, key, kwargs[key])
        self.mgmt_client = self.get_mgmt_svc_client(ComputeManagementClient,
                                                    base_url=self._cloud_environment.endpoints.resource_manager,
                                                    api_version='2021-04-01')

        if (self.instance_id is None):
            self.results['instances'] = self.list()
        else:
            self.results['instances'] = self.get()
        return self.results

    def get(self):
        response = None
        results = []
        try:
            response = self.mgmt_client.virtual_machine_scale_set_vms.get(resource_group_name=self.resource_group,
                                                                          vm_scale_set_name=self.vmss_name,
                                                                          instance_id=self.instance_id)
            self.log("Response : {0}".format(response))
        except ResourceNotFoundError as e:
            self.log('Could not get facts for Virtual Machine Scale Set VM.')

        if response and self.has_tags(response.tags, self.tags):
            results.append(self.format_response(response))

        return results

    def list(self):
        items = None
        try:
            items = self.mgmt_client.virtual_machine_scale_set_vms.list(resource_group_name=self.resource_group,
                                                                        virtual_machine_scale_set_name=self.vmss_name)
            self.log("Response : {0}".format(items))
        except ResourceNotFoundError as e:
            self.log('Could not get facts for Virtual Machine ScaleSet VM.')

        results = []
        for item in items:
            if self.has_tags(item.tags, self.tags):
                results.append(self.format_response(item))
        return results

    def format_response(self, item):
        d = item.as_dict()

        instance = None
        power_state = ''
        if d.get('provisioning_state') is not None:
            iv = self.mgmt_client.virtual_machine_scale_set_vms.get_instance_view(resource_group_name=self.resource_group,
                                                                                  vm_scale_set_name=self.vmss_name,
                                                                                  instance_id=d.get('instance_id', None)).as_dict()
            for index in range(len(iv['statuses'])):
                code = iv['statuses'][index]['code'].split('/')
                if code[0] == 'PowerState':
                    power_state = code[1]
                    break
        else:
            try:
                instance = self.compute_client.virtual_machines.instance_view(self.resource_group, d.get('instance_id', None)).as_dict()
                vm_instance = self.compute_client.virtual_machines.get(self.resource_group, d.get('instance_id', None)).as_dict()
            except Exception as exc:
                self.fail("Getting Flexible VMSS instance instance failed, name {0} instance view - {1}".format(d.get('instance_id'), str(exc)))

            for index in range(len(instance['statuses'])):
                code = instance['statuses'][index]['code'].split('/')
                if code[0] == 'PowerState':
                    power_state = code[1]
                elif code[0] == 'OSState' and code[1] == 'generalized':
                    power_state = 'generalized'
                    break
                elif code[0] == 'ProvisioningState' and code[1] == 'failed':
                    power_state = ''
                    break
        dd = {
            'resource_group': self.resource_group,
            'id': d.get('id', None),
            'tags': d.get('tags', None),
            'instance_id': d.get('instance_id', None),
            'latest_model': d.get('latest_model_applied', None),
            'name': d.get('name', None),
            'provisioning_state': d.get('provisioning_state', None),
            'power_state': power_state,
            'vm_id': d.get('vm_id', None),
        }
        if d.get('provisioning_state') is not None:
            dd['image_reference'] = d.get('storage_profile').get('image_reference', None)
            dd['computer_name'] = d.get('os_profile').get('computer_name', None)
        else:
            dd['image_reference'] = vm_instance.get('storage_profile').get('image_reference', None)
            dd['computer_name'] = vm_instance.get('os_profile').get('computer_name', None)
            dd['provisioning_state'] = vm_instance.get('provisioning_state', None)
            dd['tags'] = vm_instance.get('tags', None)
            dd['vm_id'] = vm_instance.get('vm_id')
        return dd


def main():
    AzureRMVirtualMachineScaleSetVMInfo()


if __name__ == '__main__':
    main()
