"""
Executable cli module.
"""

import os
from configparser import RawConfigParser
import logging

import click

from pyepp.cli.host import host_group
from pyepp.cli import cli
from pyepp.cli.contact import contact_group
from pyepp.cli.domain import domain_group
from pyepp.cli.poll import poll_group
from pyepp.cli import utils

logging.basicConfig(level=logging.ERROR)

CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}

APP_NAME = "pyepp"


def load_config():
    """
    Loads the configuration file into context settings. It reads the config file
    from the below paths depends on the host OS.

    Mac OS X (POSIX) and Unix (POSIX):
      ~/.pyepp/config.ini
    Windows (not roaming):
      C:\\Users\\<user>\\AppData\\Local\\pyepp\\config.ini
    """
    cfg = os.path.join(
        click.get_app_dir(APP_NAME, roaming=False, force_posix=True), "config.ini"
    )
    parser = RawConfigParser()
    parser.read([cfg])
    config = {}
    for section in parser.sections():
        for key, value in parser.items(section):
            config[f"{section}_{key}".upper()] = value

    CONTEXT_SETTINGS["default_map"] = {
        "server": config.get("PYEPP_SERVER"),
        "port": config.get("PYEPP_PORT"),
        "client_cert": config.get("PYEPP_CLIENT_CERT"),
        "client_key": config.get("PYEPP_CLIENT_KEY"),
        "user": config.get("PYEPP_USER"),
        "password": config.get("PYEPP_PASSWORD"),
    }


load_config()


@click.group(name="pyepp", context_settings=CONTEXT_SETTINGS)
@click.option("--server", envvar="PYEPP_SERVER", required=True)
@click.option("--port", envvar="PYEPP_PORT", required=True)
@click.option("--user", envvar="PYEPP_USER", required=True)
@click.option("--password", envvar="PYEPP_PASSWORD", required=True)
@click.option("--client-cert", envvar="PYEPP_CLIENT_CERT", required=False)
@click.option("--client-key", envvar="PYEPP_CLIENT_KEY", required=False)
@click.option(
    "--extension",
    envvar="PYEPP_EXTESION",
    required=False,
    help="The extension to be loaded for the EPP command.",
    multiple=True,
)
@click.option(
    "-o",
    "--output-format",
    show_default=True,
    default="XML",
    type=click.Choice(["XML", "OBJECT", "MIN"], case_sensitive=False),
)
@click.option("--no-pretty", is_flag=True, show_default=True, default=False)
@click.option("--dry-run", is_flag=True, show_default=True, default=False)
@click.option(
    "-f",
    "--file",
    type=click.File("wb"),
    help="If provided, the output will be written in the file.",
    default=None,
)
@click.option("-v", "--verbose", is_flag=True, show_default=True, default=False)
@click.option("-d", "--debug", is_flag=True, show_default=True, default=False)
@click.version_option()
@click.pass_context
# pylint: disable=too-many-arguments
def pyepp_cli(
    ctx,
    server,
    port,
    client_cert,
    client_key,
    user,
    password,
    extension,
    output_format,
    no_pretty,
    dry_run,
    file,
    verbose,
    debug,
):
    """A command line interface to work with PyEpp library."""
    ctx.obj = cli.PyEppCli(
        server,
        port,
        client_cert,
        client_key,
        user,
        password,
        extension,
        output_format,
        no_pretty,
        dry_run,
    )

    if verbose:
        logging.getLogger().setLevel(level=logging.INFO)
    if debug:
        logging.getLogger().setLevel(level=logging.DEBUG)

    utils.OUTPUT_FILE = file


@click.command("run")
@click.argument("xml", type=click.File("rb"))
@click.pass_context
def run_xml(ctx, xml):
    """Receive an XML file containing an EPP XML command and execute it.

    XML: path to an XML file
    """
    xml_command = xml.read()
    result = ctx.obj.execute(xml_command.decode("utf-8"))
    utils.echo(result)


@click.command("hello")
@click.pass_context
def hello(ctx):
    """Sends a hello command to the server and receives the Greeting response."""
    greeting = ctx.obj.hello()
    utils.echo(greeting)


pyepp_cli.add_command(run_xml)
pyepp_cli.add_command(contact_group)
pyepp_cli.add_command(domain_group)
pyepp_cli.add_command(host_group)
pyepp_cli.add_command(poll_group)
pyepp_cli.add_command(hello)
