#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""braise - a dynamic firewall

"""

# Needed to parse arguments :
import argcomplete
import argparse
import pickle
from servicewall.network_helpers import get_essid


conf_dir = "/var/lib/servicewall/"
realm_defs_pickle = conf_dir + "realms.p"
service_defs_pickle = conf_dir + "services.p"
definitions_dir = "/etc/gufw/app_profiles"
program_name = "ServiceWall"

with open(realm_defs_pickle, "rb") as fd:
    realm_defs = pickle.load(fd)
with open(service_defs_pickle, "rb") as fd:
    service_defs = pickle.load(fd)

# Find allowed services to help autocompletion know what to delete.
essid = get_essid()
allowed_services = [ service_def for service_def in realm_defs[essid].keys() ]

def helper(function_name):
    """This function will return a pointer to a function named "function_name"
    in parser_helpers. This pointer will only be evaluated when it is called,
    ie after parser is done.
    """
    def wrapper(args):
        from servicewall import parser_helpers
        eval("parser_helpers." + function_name)(args)
    return wrapper

parser = argparse.ArgumentParser()
#parser.required = True

# parser fails badly when invoked without argument ;
# let's invoke basic help instead.
parser.set_defaults(func=helper("no_arg_provided"))

subparser = parser.add_subparsers()
#subparser.required = True


#
# SUBPARSERS : enable, disable
#

parser_enable = subparser.add_parser(
    "enable",
    help="enable the firewall"
)
parser_enable.set_defaults(func=helper("enable"))

parser_disable = subparser.add_parser(
    "disable",
    help="disable the firewall"
)
parser_disable.set_defaults(func=helper("disable"))


#
# SUBPARSERS : show status, logs, realms, services, service
#

parser_show = subparser.add_parser("show")
show_subparser = parser_show.add_subparsers()

parser_show_status = show_subparser.add_parser(
    "status",
    help="show iptables rules controlled by this firewall"
)
parser_show_status.set_defaults(func=helper("show_status"))

parser_show_logs = show_subparser.add_parser(
    "logs",
    help="show logs of firewall"
)
parser_show_logs.set_defaults(func=helper("show_logs"))
show_logs_subparser = parser_show_logs.add_subparsers()
parser_show_logs_time = show_logs_subparser.add_parser(
    "since",
    help="restrict logs to those since [period] seconds"
)
parser_show_logs_time.add_argument(
    "period",
)
parser_show_logs_time.set_defaults(func=helper("show_logs"))

parser_show_realms = show_subparser.add_parser(
    "realms",
    help="show realm definitions"
)
parser_show_realms.set_defaults(func=helper("show_realms"))

parser_show_services = show_subparser.add_parser(
    "services",
    help="show services list"
)
parser_show_services.set_defaults(func=helper("show_services"))

parser_show_service = show_subparser.add_parser(
    "service",
    # don't define help ; instead overwrite the usage because
    # it prints the possible arguments twice, which is way too long
    help="prints the service definition",
    # TODO could tell to search for services with braise show services
    # and then don't display "positional arguments" - see
    # https://docs.python.org/3.2/library/argparse.html#formatter-class
    usage="%s %s service_name - prints the service definition" %
    (parser_show.prog, "service")
)
parser_show_service.add_argument(
    "service_name",
    nargs="*",
    #choices=[ name.split() for name in service_defs ],
    #help=""
)
parser_show_service.set_defaults(func=helper("show_service"))


#
# SUBPARSERS : add and del service
#

# create the parser for the "add" command
parser_add = subparser.add_parser("add")
# create the subparser for the "add service" command
add_subparser = parser_add.add_subparsers()
parser_add_service = add_subparser.add_parser(
    "service",
    usage="%s service service_name - add a service to authorized list" %
    parser_add.prog
)
parser_add_service.add_argument(
    "service_name",
    #nargs="*",
    choices=service_defs,
)
parser_add_service.set_defaults(func=helper("add_service"))

# create the parser for the "del" command
parser_del = subparser.add_parser("del")
# create the subparser for the "del service" command
del_subparser = parser_del.add_subparsers()
parser_del_service = del_subparser.add_parser(
    "service",
    usage="%s service service_name - remove a service from authorized list" %
    parser_del.prog
)
parser_del_service.add_argument(
    "service_name",
    #nargs="*",
    choices=allowed_services,
)
parser_del_service.set_defaults(func=helper("del_service"))


argcomplete.autocomplete(parser)
# Here, argcomplete stops.
args = parser.parse_args()
# Here, helper callbacks get evaluated.
args.func(args)



