#!/usr/bin/env python
import time
from ansible.module_utils.basic import *

from mist.client import MistClient


def init_client(mist_uri="https://mist.io", email=None, password=None):
    client = MistClient(mist_uri, email, password)
    return client


def supported_providers(client, provider):
    providers = client.supported_providers

    if provider == "all":
        return providers
    else:
        chosen_providers = []
        for prov in providers:
            if provider in prov['provider']:
                chosen_providers.append(prov)
        return chosen_providers


def main():
    module = AnsibleModule(
        argument_spec=dict(
            mist_uri=dict(default='https://mist.io', type='str'),
            mist_email=dict(required=False, type='str'),
            mist_password=dict(required=False, type='str'),
            backend=dict(required=True, type='str'),
            image_id=dict(required=False, type='str'),
            size_id=dict(required=False, type='str'),
            location_id=dict(required=False, type='str'),
            key=dict(required=False, type='str'),
            image_extra=dict(required=False, type='str'),
            disk=dict(required=False, type='str'),
            name=dict(required=True, type='str'),
            list_only=dict(required=False, default=False, type='bool'),
            wait=dict(required=False, default=False, type='bool'),
            wait_time=dict(required=False, default=600, type='int'),
            monitoring=dict(required=False, type='bool', default=False),
            wait_for_stats=dict(required=False, type='bool', default=False)
        )
    )

    mist_uri = module.params.get('mist_uri')
    mist_email = module.params.get('mist_email')
    mist_password = module.params.get('mist_password')

    client = init_client(mist_uri, mist_email, mist_password)

    backend_name = module.params.get('backend')
    backend = client.backends[backend_name]

    list_only = module.params.get('list_only')

    if list_only:
        machine_name = module.params.get('name')
        machine = backend.machines[machine_name]
        module.exit_json(changed=False, machine=machine.info)

    key_name = module.params.get('key')
    key = client.keys[key_name]

    image_id = module.params.get('image_id')
    size_id = module.params.get('size_id')
    location_id = module.params.get('location_id')
    image_extra = module.params.get('image_extra')
    disk = module.params.get('disk')

    machine_name = module.params.get('name')

    backend.create_machine(machine_name, key, image_id, location_id, size_id, image_extra, disk)
    backend.update_machines()

    machine = backend.machines[machine_name]

    wait = module.params.get('wait')
    if not wait:
        module.exit_json(changed=True, machine=machine.info)
    else:
        wait_time = module.params.get('wait_time')
        monitoring = module.params.get('monitoring')
        wait_for_stats = module.params.get('wait_for_stats')
        start_time = time.time()
        while time.time() < start_time + wait_time:
            try:
                time.sleep(15)
                probe_info = machine.probe()
                uptime = probe_info.get('uptime', None)
                if uptime:
                    backend.update_machines()
                    machine = backend.machines[machine_name]

                    break
            except:
                backend.update_machines()
                machine = backend.machines[machine_name]

        if monitoring and wait_for_stats:
            machine.enable_monitoring()
            start_time = time.time()
            while time.time() < start_time + wait_time:
                try:
                    time.sleep(15)
                    stats = machine.get_stats()
                    if stats:
                        break
                except:
                    backend.update_machines()
                    machine = backend.machines[machine_name]
        elif monitoring:
            machine.enable_monitoring()

        info = machine.info
        network_interfaces = info['extra'].get('network_interfaces', None)
        if network_interfaces:
            info['extra'].pop('network_interfaces')

        module.exit_json(changed=True, machine=info)


main()