#!/usr/bin/python

from ansible.module_utils.basic import *
import requests
import json

class InfluxdbPrivilege:
  def __init__(self, user, database, privilege, api_host, api_port, api_user, api_password):
    self.user = user
    self.database = database
    self.privilege = privilege
    self.api_host = api_host
    self.api_port = api_port
    self.api_user = api_user
    self.api_password = api_password
    self.change = False
    self.get_info()

  def request(self, query):
    url = 'http://{}:{}/query?q={}'.format(self.api_host, self.api_port, requests.utils.quote(query))
    
    if self.api_user is not None:
      r = requests.get(url, auth=(self.api_user, self.api_password))
    else:
      r = requests.get(url)
      
    if r.status_code != 200:
      raise Exception('Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text))
    
    return json.loads(r.text)

  def get_info(self):
    privileges = self.request(
      'SHOW GRANTS FOR {}'.format(self.user),
    )['results'][0]['series'][0]

    if 'values' in privileges:
      for privilege in privileges['values']:
        if self.database == privilege[0]:
          self.exist = True
          if self.privilege != privilege[1]:
            self.change = True
          return

    self.exist = False

  def grant(self):
    self.request(
      'GRANT {} ON {} TO {}'.format(self.privilege, self.database, self.user)
    )

  def revoke(self):
    self.request(
      'REVOKE {} ON {} FROM {}'.format(self.privilege, self.database, self.user)
    )
  

def main():
  fields = {
    'user':         { 'type': 'str', 'required': True },
    'database':     { 'type': 'str', 'required': True },
    'privilege':   { 'type': 'str', 'required': True, 'choices': ['ALL', 'WRITE', 'READ'] },
    'api_user':     { 'type': 'str' },
    'api_password': { 'type': 'str' },
    'api_host':     { 'type': 'str', 'default': '127.0.0.1' },
    'api_port':     { 'type': 'int', 'default': 8086 },
    'state':        { 'type': 'str', 'default': 'present', 'choices': ['present', 'absent'] }
  }
  module = AnsibleModule(argument_spec=fields)
  changed = False

  influxdb_privilege = InfluxdbPrivilege(
    module.params['user'],
    module.params['database'],
    module.params['privilege'],
    module.params['api_host'],
    module.params['api_port'],
    module.params['api_user'],
    module.params['api_password']
  )

  if module.params['state'] == 'present':
    if not influxdb_privilege.exist or influxdb_privilege.change:
      influxdb_privilege.grant()
      changed = True
  else:
    if influxdb_privilege.exist:
      influxdb_privilege.revoke()
      changed = True
 
  module.exit_json(changed=changed)

if __name__ == '__main__':
  main()