#! /usr/bin/env python

"""
usage: %prog [args]
"""

import rospkg

from argparse import ArgumentParser
import os
import sys
import yaml

import app_manager
import rospy


def main():
    rospy.init_node('app_manager')

    argv = rospy.myargv()
    parser = ArgumentParser()

    parser.add_argument("--applist", default=None, nargs="*",
                        help="path to applist directories", metavar="PATH")
    args = parser.parse_args(argv[1:])

    applist = []
    plugin_yamls = []
    rospack = rospkg.RosPack()
    depend_pkgs = rospack.get_depends_on('app_manager', implicit=False)

    rospy.loginfo("Loading from plugin definitions")
    for depend_pkg in depend_pkgs:
        manifest = rospack.get_manifest(depend_pkg)
        app_dirs = manifest.get_export('app_manager', 'app_dir')
        plugin_yaml = manifest.get_export('app_manager', 'plugin')
        if len(app_dirs) != 0:
            applist += app_dirs
            for app_dir in app_dirs:
                rospy.logdebug('Loading app in {}'.format(app_dir))
        if len(plugin_yaml) != 0:
            plugin_yamls += plugin_yaml
            for plugin_y in plugin_yaml:
                rospy.logdebug('Loading plugin in {}'.format(plugin_y))

    if args.applist is not None:
        rospy.loginfo("Loading applist from --applist option")
        for path in args.applist:
            if not os.path.exists(path):
                rospy.logerr(
                    "applist directory {} does not exist."
                    "Use --applist to set the correct location".format(path))
        applist += args.applist

    if len(applist) == 0:
        rospy.logwarn('No applist directory found.')

    plugins = []
    for plugin_yaml in plugin_yamls:
        with open(plugin_yaml) as f:
            plugin = yaml.safe_load(f)
        plugins += plugin

    robot_name = rospy.get_param('/robot/name', 'robot')
    robot_type = rospy.get_param("/robot/type", None)
    sigint_timeout = rospy.get_param("~sigint_timeout", 15.0)
    sigterm_timeout = rospy.get_param("~sigterm_timeout", 2.0)
    if robot_type is None:
        rospy.loginfo("The param '/robot/type' is undefined. Using apps for any platforms")
    else:
        rospy.loginfo("Using apps for platform '%s'" % robot_type)

    interface_master = rospy.get_param('~interface_master', 'http://localhost:11312')

    try:
        app_list = app_manager.AppList(applist, platform=robot_type)
    except app_manager.AppException as e:
        rospy.logerr("Failed to load app list: {}".format(e))
        sys.exit(1)

    exchange = None

    exchange_url = rospy.get_param('/robot/exchange_url', '')
    if (exchange_url != ""):
        try:
            app_path = os.path.join(rospkg.get_ros_home(), "exchange")
            if (not os.path.exists(app_path)):
                os.makedirs(app_path)
            exchange = app_manager.Exchange(exchange_url, app_path, lambda x: rospy.logerr(x))
            app_list.add_directory(os.path.join(app_path, "installed"))
        except app_manager.AppException as e:
            rospy.logerr("Failed to load exchange: {}".format(e))
            sys.exit(1)

    enable_app_replacement = rospy.get_param('~enable_app_replacement', True)
    enable_topic_remapping = rospy.get_param('~enable_topic_remapping', True)

    am = app_manager.AppManager(
        robot_name, interface_master, app_list, exchange, plugins,
        enable_app_replacement=enable_app_replacement,
        enable_topic_remapping=enable_topic_remapping,
        sigint_timeout=sigint_timeout, sigterm_timeout=sigterm_timeout)

    rospy.on_shutdown(am.shutdown)

    rospy.spin()



if __name__ == "__main__":
    main()
