#!/usr/bin/python3

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


class InfluxdbUser:
    def __init__(self, api_url, api_token, name):
        self.api_url = api_url
        self.headers = {'Authorization': 'Token {}'.format(api_token)}
        self.name = name

    def exists(self):
        url = '{}/api/v2/users'.format(self.api_url)
        r = requests.get(
            url,
            headers=self.headers,
            params={'name': self.name}
        )

        if r.status_code == 404:
            return False
        elif r.status_code == 200:
            data = json.loads(r.text)
            for user in data['users']:
                if user['name'] == self.name:
                    self.id = user['id']
                    self.status = user['status']
                    return True
            return False

        raise Exception(
            'Influxdb',
            'Bad status code {}: {}'.format(r.status_code, r.text)
        )

    def has_changed(self, status):
        if self.status != status:
            return True
        return False

    def create(self, status):
        url = '{}/api/v2/users'.format(self.api_url)
        r = requests.post(
            url,
            headers=self.headers,
            json={
                'name': self.name,
                'status': status
            }
        )

        if r.status_code != 201:
            raise Exception(
                'Influxdb',
                'Bad status code {}: {}'.format(r.status_code, r.text)
            )

    def delete(self):
        url = '{}/api/v2/users/{}'.format(self.api_url, self.id)
        r = requests.delete(url, headers=self.headers)

        if r.status_code != 204:
            raise Exception(
                'Influxdb',
                'Bad status code {}: {}'.format(r.status_code, r.text)
            )

    def update(self, status):
        url = '{}/api/v2/users/{}'.format(self.api_url, self.id)
        r = requests.patch(
            url,
            headers=self.headers,
            json={
                'name': self.name,
                'status': status
            }
        )

        if r.status_code != 200:
            raise Exception(
                'Influxdb',
                'Bad status code {}: {}'.format(r.status_code, r.text)
            )


def main():
    fields = {
        'name':      {'type': 'str', 'required': True},
        'status':    {'type': 'str',
                      'default': 'active',
                      'choice': ['active', 'inactive']},
        'api_url':   {'type': 'str', 'default': 'http://127.0.0.1:8086'},
        'api_token': {'type': 'str', 'required': True},
        'state':     {'type': 'str',
                      'default': 'present',
                      'choice': ['present', 'absent']},
    }
    module = AnsibleModule(argument_spec=fields)

    user = InfluxdbUser(
        module.params['api_url'],
        module.params['api_token'],
        module.params['name'],
    )
    changed = False

    if user.exists():
        if module.params['state'] == 'absent':
            user.delete()
            changed = True
        elif user.has_changed(module.params['status']):
            user.update(module.params['status'])
            changed = True
    elif module.params['state'] == 'present':
        user.create(module.params['status'])
        changed = True

    module.exit_json(changed=changed)


if __name__ == '__main__':
    main()