#!/usr/bin/python

# (c) 2018, NetApp, Inc
# 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


ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'certified'}


DOCUMENTATION = '''

module: na_ontap_disks

short_description: NetApp ONTAP Assign disks to nodes
extends_documentation_fragment:
    - netapp.na_ontap
version_added: '2.7'
author: NetApp Ansible Team (ng-ansibleteam@netapp.com)

description:
- Assign all or part of disks to nodes.

options:

  node:
    required: true
    description:
    - It specifies the node to assign all visible unowned disks.

'''

EXAMPLES = """
- name: Assign unowned disks
  na_ontap_disks:
    node: cluster-01
    hostname: "{{ hostname }} "
    username: "{{ admin username }}"
    password: "{{ admin password }}"
"""

RETURN = """

"""
import traceback

from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
import ansible.module_utils.netapp as netapp_utils


HAS_NETAPP_LIB = netapp_utils.has_netapp_lib()


class NetAppOntapDisks(object):
    ''' object initialize and class methods '''

    def __init__(self):
        self.argument_spec = netapp_utils.na_ontap_host_argument_spec()
        self.argument_spec.update(dict(
            node=dict(required=True, type='str'),
        ))

        self.module = AnsibleModule(
            argument_spec=self.argument_spec,
            supports_check_mode=True
        )

        parameters = self.module.params

        # set up state variables
        self.node = parameters['node']

        if HAS_NETAPP_LIB is False:
            self.module.fail_json(msg="the python NetApp-Lib module is required")
        else:
            self.server = netapp_utils.setup_na_ontap_zapi(module=self.module)

    def disk_check(self):
        """
        Check for disks
        """
        disk_iter = netapp_utils.zapi.NaElement('storage-disk-get-iter')
        disk_storage_info = netapp_utils.zapi.NaElement('storage-disk-info')
        disk_raid_info = netapp_utils.zapi.NaElement('disk-raid-info')
        disk_raid_info.add_new_child('container-type', 'unassigned')
        disk_storage_info.add_child_elem(disk_raid_info)

        disk_query = netapp_utils.zapi.NaElement('query')
        disk_query.add_child_elem(disk_storage_info)

        disk_iter.add_child_elem(disk_query)
        result = self.server.invoke_successfully(disk_iter, True)

        if result.get_child_by_name('num-records') and \
                int(result.get_child_content('num-records')) >= 1:
            has_disks = "true"
            return has_disks

    def disk_assign(self):
        """
        enable aggregate (online).
        """
        assign_disk = netapp_utils.zapi.NaElement.create_node_with_children(
            'disk-sanown-assign', **{'node-name': self.node,
                                     'all': 'true'})
        try:
            self.server.invoke_successfully(assign_disk,
                                            enable_tunneling=True)
            return True
        except netapp_utils.zapi.NaApiError as error:
            if to_native(error.code) == "13001":
                # Error 13060 denotes aggregate is already online
                return False
            else:
                self.module.fail_json(msg='Error assigning disks %s' %
                                      (to_native(error)),
                                      exception=traceback.format_exc())

    def apply(self):
        '''Apply action to disks'''
        changed = False
        results = netapp_utils.get_cserver(self.server)
        cserver = netapp_utils.setup_na_ontap_zapi(
            module=self.module, vserver=results)
        netapp_utils.ems_log_event("na_ontap_disks", cserver)

        # check if anything needs to be changed (add/delete/update)
        unowned_disks = self.disk_check()
        if unowned_disks == 'true':
            self.disk_assign()
            changed = True
        self.module.exit_json(changed=changed)


def main():
    ''' Create object and call apply '''
    obj_aggr = NetAppOntapDisks()
    obj_aggr.apply()


if __name__ == '__main__':
    main()
