#!/usr/bin/env python

import logging
import sys
import traceback

from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks

from aiki.cli import make_arg_parser, setup_logging
from juju.environment.config import EnvironmentsConfig
from juju.errors import EnvironmentNotFound
from juju.lib.format import YAMLFormat


log = logging.getLogger("provider-info")


def main():
    parser = make_parser()
    options = parser.parse_args()
    setup_logging(options)
    run_command(get_info, options)


def make_parser(root_parser=None):
    main_parser = make_arg_parser(
        root_parser, "provider-info",
        description="Gets the available provider info for specified environment")
    return main_parser


def get_provider(options):
    env_config = EnvironmentsConfig()
    env_config.load()
    if options.environment is None:
        environment = env_config.get_default()
    else:
        environment = env_config.get(options.environment)
    if environment is None:
        raise EnvironmentNotFound(
            "Environment %r not configured in environments.yaml" % options.environment)
    return environment.get_machine_provider()


def run_command(command, options):
    try:
        provider = get_provider(options)
    except Exception, e:
        print >> sys.stderr, e
        sys.exit(1)

    exit_code = [0]
    reactor.callWhenRunning(run_command_in_reactor, command, exit_code, provider, options)
    reactor.run()
    sys.exit(exit_code[0])


@inlineCallbacks
def run_command_in_reactor(command, exit_code, provider, options):
    try:
        yield command(exit_code, provider, options)
    except Exception, e:
        exit_code[0] = 1
        if options.verbose:
            traceback.print_exc()  # Writes to stderr
        else:
            print >> sys.stderr, e
    finally:
        reactor.stop()


@inlineCallbacks
def get_info(result, provider, options):
    info = {
        "machines": [], 
        "provider-state": (yield provider.load_state())}
    machines = yield provider.get_machines()
    for machine in machines:
	info["machines"].append(dict(
                dns_name=machine.dns_name, private_dns_name=machine.private_dns_name,
		instance_id=machine.instance_id,  state=machine.state))
    print YAMLFormat().format(info)


if __name__ == '__main__':
    main()
