#! /usr/bin/env python3
"""A Minecraft RCON client."""

from argparse import ArgumentParser
from getpass import getpass
from logging import DEBUG, INFO, basicConfig, getLogger
from sys import exit    # pylint: disable=W0622

from mcipc.config import LOG_FORMAT, InvalidCredentialsError, Credentials
from mcipc.rcon.config import CONFIG
from mcipc.rcon.playground import Client


LOGGER = getLogger(__file__)


def get_args():
    """Parses and returns the CLI arguments."""

    parser = ArgumentParser(description='A Minecraft RCON client.')
    parser.add_argument('server', help="the server's name")
    subparsers = parser.add_subparsers(dest='action')
    command_parser = subparsers.add_parser(
        'exec', help='execute commands on the server')
    command_parser.add_argument(
        'command', help='command to execute on the server')
    command_parser.add_argument(
        'argument', nargs='*', default=(), help='arguments for the command')
    fortune_parser = subparsers.add_parser(
        'fortune', help='send a fortune to the players on the server')
    fortune_parser.add_argument(
        '-l', '--long', action='store_true', help='generate ling fortunes')
    fortune_parser.add_argument(
        '-o', '--offensive', action='store_true',
        help='generate offensive fortunes')
    datetime_parser = subparsers.add_parser(
        'datetime',
        help='sends the current date and time to the players on the server')
    datetime_parser.add_argument(
        '-f', '--format', default='%c', help='the datetime format')
    parser.add_argument(
        '-d', '--debug', action='store_true',
        help='print additional debug information')
    return parser.parse_args()


def main():
    """Runs the RCON client."""

    args = get_args()
    log_level = DEBUG if args.debug else INFO
    basicConfig(level=log_level, format=LOG_FORMAT)
    server = args.server

    try:
        host, port, passwd = Credentials.from_string(server)
    except InvalidCredentialsError:
        try:
            host, port, passwd = CONFIG.servers[server]
        except KeyError:
            LOGGER.error('No such server: %s.', server)
            exit(2)

    if passwd is None:
        try:
            passwd = getpass('Password: ')
        except (KeyboardInterrupt, EOFError):
            print()
            LOGGER.error('Aborted by user.')
            exit(3)

    with Client(host, port) as client:
        if client.login(passwd):
            if args.action == 'datetime':
                result = client.datetime(frmt=args.format)
            elif args.action == 'fortune':
                result = client.fortune(
                    short=not args.long, offensive=args.offensive)
            elif args.action == 'exec':
                result = client.run(args.command, *args.argument)

            if result:
                LOGGER.info(result)
        else:
            LOGGER.error('Failed to log in.')
            exit(1)


if __name__ == '__main__':
    main()
