#!/usr/bin/python

from ansible.module_utils.basic import *
from ansible.module_utils.elasticsearch_api import *

class ElasticsearchRole:
    def __init__(self, api_url, api_user, api_password, name, cluster, indices):
        self.api = ElasticsearchApi(
            api_url,
            api_user,
            api_password
        )
        self.api_url  = api_url
        self.name     = name
        self.cluster  = cluster
        self.indices  = indices
        self.exist    = False
        self.data     = {}

    def get_data(self):
        status_code, data = self.api.get('_security/role/{}'.format(self.name))
        if status_code == 200:
            self.exist = True
            self.data  = data[self.name]

    def array_has_changed(self, list1, list2):
        for item in list1:
            if item not in list2:
                return True

        for item in list2:
            if item not in list1:
                return True

        return False

    def cluster_has_changed(self):
        return self.array_has_changed(self.cluster, self.data['cluster'])

    def same_indice(self, indice1, indice2):
        if self.array_has_changed(indice1['names'], indice2['names']):
            return False

        if self.array_has_changed(indice1['privileges'], indice2['privileges']):
            return False
        
        return True

    def indices_have_changed(self):
        for indice1 in self.indices:
            exist = False
            for indice2 in self.data['indices']:
                if self.same_indice(indice1, indice2):
                    exist = True
                    break
            if not exist:
                return True

        for indice1 in self.data['indices']:
            exist = False
            for indice2 in self.indices:
                if self.same_indice(indice1, indice2):
                    exist = True
                    break
            if not exist:
                return True

        return False

    def has_changed(self):
        if self.cluster_has_changed():
            return True

        if self.indices_have_changed():
            return True

        return False

    def create(self):
        self.api.put(
            '_security/role/{}'.format(self.name),
            {
                'cluster': self.cluster,
                'indices': self.indices
            }
        )

    def delete(self):
        self.api.delete('_security/role/{}'.format(self.name))

        
def main():
    fields = {
        'name':         { 'type': 'str', 'required': True },
        'indices':      { 'type': 'list', 'default': [] },
        'cluster':      { 'type': 'list', 'default': [] },
        'api_url':      { 'type': 'str', 'default': 'http://127.0.0.1:9200' },
        'api_user':     { 'type': 'str', 'default': None },
        'api_password': { 'type': 'str', 'default': None, 'no_log': True },
        'state':        { 'type': 'str', 'default': 'present', 'choice': ['present', 'absent'] },
    }
    module = AnsibleModule(argument_spec=fields)
    changed = False

    role = ElasticsearchRole(
        module.params['api_url'],
        module.params['api_user'],
        module.params['api_password'],
        module.params['name'],
        module.params['cluster'],
        module.params['indices'],
    )
    role.get_data()

    if module.params['state'] == 'present':
        if not role.exist or role.has_changed():
            role.create()
            changed = True
    elif user.exist:
        role.delete()
        changed = True

    module.exit_json(changed=changed)

if __name__ == '__main__':
    main()