#!/usr/bin/env python
#coding=utf8


import os
import argparse

from kolekto.printer import printer
from kolekto.exceptions import KolektoRuntimeError
from kolekto.config import parse_config
from kolekto.profiles import NoProfileProfile


def find_root():
    """ Find the root path of the Kolekto tree from the current working directory.

    If function doesn't find a Kolekto tree, it returns the cwd.
    :return: the path to the root directory of Kolekto tree.
    """

    cwd = os.getcwd()
    while cwd != '/':
        config = os.path.join(cwd, '.kolekto')
        if os.path.exists(config):
            return cwd
        else:
            cwd, _ = os.path.split(cwd)
    else:
        return os.getcwd()


def main():
    """ Binary entry-point.
    """

    # Create a bootstrap argument parser only used to set the used tree to
    # know the configuration to parse before to continue:
    bootstrap_parser = argparse.ArgumentParser(add_help=False)
    bootstrap_parser.add_argument('-t', '--tree', default=find_root())

    args, __ = bootstrap_parser.parse_known_args()

    # Parse configuration:
    try:
        config = parse_config(os.path.join(args.tree, '.kolekto', 'config'))
    except IOError as err:
        if err.errno == 2:
            config = None
        else:
            raise

    if config is None:
        profile = NoProfileProfile('no-profile', None)
    else:
        profile_name, profile_class = config.get('profile')
        profile = profile_class(profile_name, config)

    # Create the final argument parser:
    aparser = argparse.ArgumentParser()
    aparser.add_argument('-t', '--tree', default=find_root())
    aparser.add_argument('-e', '--editor', default=os.environ.get('EDITOR', 'vim'))
    aparser.add_argument('-d', '--debug', action='store_true', default=False)
    aparser.add_argument('-V', '--verbose', action='store_true', default=False)
    aparser_subs = aparser.add_subparsers(help='Kolekto commands')

    # Register all the kolekto commands for the profile:
    profile.load_commands(aparser_subs)

    # Parse the command line arguments:
    args = aparser.parse_args()

    # Configure the main printer:
    printer.configure(verbose=args.verbose, debug=args.debug, editor=args.editor)

    # Execute the selected command:
    printer.debug('Executing command {cmd}', cmd=args.command)
    try:
        args.command(args, config)
    except KolektoRuntimeError as err:
        printer.p('Error: {error}', error=err)
    except KeyboardInterrupt:
        printer.p('Interrupted by user.')

if __name__ == '__main__':
    main()
