#!/usr/bin/env python
#
# This file is part of REPA: Release Engineering Process Assistant.
#
# Copyright (C) 2013 Intel Corporation
#
# REPA is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.

"""
REPA: Release Engineering Process Assistant.

Copyright (C) Intel Corporation 2013
Licence: GPL version 2
Author: Ed Bartosh <eduard.bartosh@intel.com>

Main module.
Command line parsing, script entry point.
"""

import sys
import pkg_resources
import ConfigParser

from os.path import expanduser
from argparse import ArgumentParser

from repa.common import RepaException


def parse_args(argv):
    """
    Parse command line. Read config.
    Set arguments to config values.
    """
    # create parser to parse -section
    parser = ArgumentParser(add_help=False)
    parser.add_argument('-section', default='general')

    # read config section, specified in command line
    parsed, argv = parser.parse_known_args(argv)
    config = read_config(section=parsed.section)

    # recreate parser to parse rest of the command line
    parser = ArgumentParser(prog='repa',
                   description='Release Engineering Process Assistant')
    parser.add_argument('--version', action='version',
                        version='%(prog)s version 0.2')
    parser.add_argument('-s', '--section', default='general',
                        help='config section to use')
    parser.add_argument('-p', '--project', help='target project',
                        default=config.get('project'))
    parser.add_argument('-c', '--colorize', action='store_true',
                        help='colorize the output',
                        default=config.get('colorize', '').lower() == 'on')

    subparsers = parser.add_subparsers(help='sub-command help')
    for entry in pkg_resources.iter_entry_points(group='repa_commands'):
        cmd = entry.load()()
        parser_cmd = subparsers.add_parser(cmd.name,
                                           description=cmd.description,
                                           help=cmd.help)
        if hasattr(cmd, 'add_arguments'):
            cmd.add_arguments(parser_cmd, config)
        parser_cmd.set_defaults(func=cmd.run)

    args = parser.parse_args(argv)

    return update_args(config, args)


def read_config(paths=('/etc/repa.conf', expanduser('~/.repa.conf')),
                section='general',
                mandatory=('apiurl', 'apiuser', 'apipasswd', 'project')):
    """
    Read repa config.
    Configuration is read from the set of files provided.
    Optional section name can be specified to read options from
    """
    conf = ConfigParser.RawConfigParser()
    if not conf.read(paths):
        raise RepaException("Configuration file not found")
    if not conf.has_section(section):
        raise RepaException("Section '%s' doesn't exist in config" % section)

    # read configuration from 'general' and then from specified section
    # to have defaults set properly
    config = dict(conf.items('general'))
    if section != 'general':
        config.update(conf.items(section))

    # Check mandatory config options
    missed = set(mandatory).difference(set(config.keys()))
    if missed:
        raise RepaException("Missing mandatory config options: %s" % \
                                ','.join(missed))
    return config

def update_args(config, args):
    """Set configuration options as args attributes."""
    for key, val in config.iteritems():
        if not hasattr(args, key):
            setattr(args, key, val)
    return args

def sub_main(argv, cmd):
    """Subcommand entry point."""
    parser = ArgumentParser(description=cmd.description)
    config = read_config()
    cmd.add_arguments(parser, config)
    args = parser.parse_args(argv)
    return cmd.run(update_args(config, args))


def main(argv=sys.argv[1:]):
    """Command line entry point."""
    try:
        args = parse_args(argv)
        return args.func(args)
    except (RepaException, KeyboardInterrupt) as error:
        print >> sys.stderr, error


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
