#!/usr/bin/env python
"""
This module is the main entry point for generating vehicle interface source code
from JSON mappings.

Given one or more JSON mapping filenames, and a list of directories where
configuration files may be found, it parses the mappings, validates them, and
prints the resulting source to stdout.
"""


import sys
import argparse
import logging

from openxc.generator.coder import CodeGenerator
from openxc.generator.message_sets import JsonMessageSet
from openxc.utils import fatal_error, load_json_from_search_path
from .common import configure_logging

LOG = logging.getLogger(__name__)

DEFAULT_SEARCH_PATH = "."


def parse_options():
    parser = argparse.ArgumentParser(description="Generate C++ source code "
            "from CAN signal descriptions in JSON")

    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument("-m", "--message-sets",
            type=str,
            nargs='+',
            dest="message_sets",
            metavar="MESSAGE_SET",
            help="generate source from these JSON-formatted message "
                    "set definitions")
    group.add_argument("--super-set",
            type=str,
            dest="super_set",
            metavar="SUPERSET",
            help="generate source with multiple active message sets, defined in"
                    " this JSON-formatted superset")
    parser.add_argument("-s", "--search-paths",
            type=str,
            nargs='+',
            dest="search_paths",
            metavar="PATH",
            help="add directories to the search path when using relative paths")

    return parser.parse_args()


def main():
    configure_logging()
    arguments = parse_options()

    search_paths = arguments.search_paths or []
    search_paths.insert(0, DEFAULT_SEARCH_PATH)

    message_sets = arguments.message_sets or []
    if arguments.super_set is not None:
        super_set_data = load_json_from_search_path(arguments.super_set,
                arguments.search_paths)
        super_set_message_sets = super_set_data.get('message_sets', [])
        if len(super_set_message_sets) == 0:
            LOG.warning("Superset '%s' has no message sets" %
                    super_set_data.get('name', 'unknown'))
        message_sets.extend(super_set_message_sets)

    generator = CodeGenerator(search_paths)
    for filename in message_sets:
        message_set = JsonMessageSet.parse(filename, search_paths=search_paths,
                skip_disabled_mappings=True)
        if not message_set.validate_messages() or not message_set.validate_name():
            fatal_error("unable to generate code")
        generator.message_sets.append(message_set)

    # TODO dump to a filename or pipe instead
    print(generator.build_source())


if __name__ == "__main__":
    sys.exit(main())
