#!/usr/bin/env python

"""Simple command line interface for making Discourse API queries."""

import cmd
import json
import logging
import optparse
import os
import pydoc
import sys

from pydiscourse.client import DiscourseClient, DiscourseError


class DiscourseCmd(cmd.Cmd):
    """Handles CLI commands"""

    prompt = "discourse>"
    output = sys.stdout

    def __init__(self, client):
        """Initialize command"""
        cmd.Cmd.__init__(self)
        self.client = client
        self.prompt = "%s>" % self.client.host

    def __getattr__(self, attr):
        """Gets attributes with dynamic name handling"""
        if attr.startswith("do_"):
            method = getattr(self.client, attr[3:])

            def wrapper(arg):
                args = arg.split()
                kwargs = dict(a.split("=") for a in args if "=" in a)
                args = [a for a in args if "=" not in a]
                try:
                    return method(*args, **kwargs)

                except DiscourseError as e:
                    print(e, e.response.text)
                    return e.response

            return wrapper

        elif attr.startswith("help_"):
            method = getattr(self.client, attr[5:])

            def wrapper():
                self.output.write(pydoc.render_doc(method))

            return wrapper

        raise AttributeError

    def postcmd(self, result, line):
        """Writes output of the command to console"""
        try:
            json.dump(
                result, self.output, sort_keys=True, indent=4, separators=(",", ": ")
            )
        except TypeError:
            self.output.write(result.text)


def main():
    """Runs the CLI application"""
    op = optparse.OptionParser()
    op.add_option("--host", default="http://localhost:4000")
    op.add_option("--api-user", default="system")
    op.add_option("-v", "--verbose", action="store_true")

    options, args = op.parse_args()
    if not options.host.startswith("http"):
        op.error("host must include protocol, eg http://")

    api_key = os.environ.get("DISCOURSE_API_KEY")
    if not api_key:
        op.error("please set DISCOURSE_API_KEY")

    client = DiscourseClient(options.host, options.api_user, api_key)

    if options.verbose:
        logging.basicConfig()
        logging.getLogger().setLevel(logging.DEBUG)

    c = DiscourseCmd(client)
    if args:
        line = " ".join(args)
        result = c.onecmd(line)
        c.postcmd(result, line)
    else:
        c.cmdloop()


if __name__ == "__main__":
    main()
