#!/usr/bin/python

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

class ElasticsearchTemplate:
  def __init__(self, api, name):
    self.api   = api
    self.name  = name
    self.exist = False
    self.data  = {}

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

  def dict_has_changed(self, new_data, data):
    for option, value in new_data.items():
      if not option in data:
        if value:
          return True

      elif type(value) is dict:
        if not type(data[option]) is dict:
          return True
        for k, v in value.items():
          if not k in data[option]:
            return True
          if str(data[option][k]) != str(v):
            return True

      elif type(value) is list:
        if not type(data[option]) is list:
          return True
        if data[option].sort() != value.sort():
          return True

      elif data[option] != value:
        return True

    return False

  def has_changed(self, options):
    if options['index_patterns'].sort() != self.data['index_patterns'].sort():
      return True

    if options['settings']:
      if self.dict_has_changed(options['settings'], self.data['settings']):
        return True
    elif self.data['settings']:
      return True

    if options['mappings']['properties']:
      if not self.data['mappings']:
        return True
      elif self.dict_has_changed(options['mappings']['properties'], self.data['mappings']['properties']):
        return True
    else:
      if self.data['mappings']:
        return True

    return False

  def create(self, options):
    self.api.put(
      '_template/{}'.format(self.name),
      options
    )
    
def main():
  fields = {
    'name':           { 'type': 'str',  'required': True },
    'index_patterns': { 'type': 'list', 'default': [] },
    'settings':       { 'type': 'dict', 'default': {} },
    'mappings':       { 'type': 'dict', '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 },
  }
  module = AnsibleModule(argument_spec=fields)
  changed = False

  options = {
    'index_patterns': module.params['index_patterns'],
    'settings':       module.params['settings'],
    'mappings': {
      'properties':   module.params['mappings'],
    },
  }

  api = ElasticsearchApi(
    module.params['api_url'],
    module.params['api_user'],
    module.params['api_password']
  )

  template = ElasticsearchTemplate(
    api,
    module.params['name'],
  )
  template.get_data()

  if not template.exist or template.has_changed(options):
    template.create(options)
    changed = True

  module.exit_json(changed=changed)

if __name__ == '__main__':
  main()