#!/usr/bin/python3
# -*- coding: utf-8 -*-

# Copyright (C) 2012-2014 Stéphane Graber
# Author: Stéphane Graber <stgraber@ubuntu.com>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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 can find the license on Debian systems in the file
# /usr/share/common-licenses/GPL-2

# NOTE: To remove once the API is stabilized
import warnings
warnings.filterwarnings("ignore", "The python-lxc API isn't yet stable")

import argparse
import configparser
import gettext
import os
import subprocess
import sys

_ = gettext.gettext
gettext.textdomain("edubuntu-server-manage")

# Some constants
EDUBUNTU_GLOBAL_CONF = "/etc/edubuntu-server/edubuntu-server.conf"
EDUBUNTU_CONTAINERS_CONF = "/etc/edubuntu-server/containers.conf"
EDUBUNTU_RUN = "/run/edubuntu-server.state"
LXC_LIB = "/var/lib/lxc/"
LXC_CACHE = "/var/cache/lxc/"


# The various functions
def start():
    # Load the config
    global_config = configparser.ConfigParser()
    global_config.read(EDUBUNTU_GLOBAL_CONF)
    containers_config = configparser.ConfigParser()
    containers_config.read(EDUBUNTU_CONTAINERS_CONF)

    # Setup the bridge
    bridge_name = global_config.get("network", "bridge_name")
    bridge_interface = global_config.get("network",
                                         "bridge_interface", fallback=None)
    gateway = ipaddr.IPv4Address(global_config.get("network", "gateway"))
    network = ipaddr.IPv4Network(global_config.get("network", "subnet"))

    subprocess.call(['brctl', 'addbr', bridge_name])
    if bridge_interface:
        subprocess.call(['ip', 'link', 'set', 'dev', bridge_interface, 'up'])
        subprocess.call(['brctl', 'addif', bridge_name, bridge_interface])
    subprocess.call(['ip', '-4', 'addr', 'add', 'dev', bridge_name, "%s/%s" %
                     (gateway, network.prefixlen)])
    subprocess.call(['ip', 'link', 'set', 'dev', bridge_name, 'up'])

    # Setup the NAT
    subprocess.call(['iptables', '-t', 'nat', '-A', 'POSTROUTING',
                     '-s', str(network), '!', '-d', str(network),
                     '-j', 'MASQUERADE'])

    # Spawn the containers
    for entry in containers_config.sections():
        if containers_config.getboolean(entry, 'autostart'):
            container = lxc.Container(entry)

            # Skip any running container
            if container.running:
                continue

            container.start()
            if not container.wait("RUNNING", 30):
                print(_("Failed to start container: %s" % entry))


def stop():
    # Load the config
    global_config = configparser.ConfigParser()
    global_config.read(EDUBUNTU_GLOBAL_CONF)
    containers_config = configparser.ConfigParser()
    containers_config.read(EDUBUNTU_CONTAINERS_CONF)

    # Stop the containers
    for entry in containers_config.sections():
        if containers_config.getboolean(entry, 'autostart'):
            container = lxc.Container(entry)

            # Skip any stopped container
            if not container.running:
                continue

            container.stop()
            if not container.wait("STOPPED", 30):
                print(_("Failed to stop container: %s" % entry))

    # Teardown the NAT
    network = ipaddr.IPv4Network(global_config.get("network", "subnet"))
    subprocess.call(['iptables', '-t', 'nat', '-D', 'POSTROUTING',
                     '-s', str(network), '!', '-d', str(network),
                     '-j', 'MASQUERADE'])
    # Destroy the bridge
    bridge_name = global_config.get("network", "bridge_name")

    subprocess.call(['ip', 'link', 'set', 'dev', bridge_name, 'down'])
    subprocess.call(['brctl', 'delbr', bridge_name])


def status():
    pass

# Begin parsing the command line
parser = argparse.ArgumentParser(description=_("Edubuntu server manager"),
                                 formatter_class=argparse.RawTextHelpFormatter)

# Required argument
sp = parser.add_subparsers()
sp_start = sp.add_parser("start", help=_("Start Edubuntu server"))
sp_start.set_defaults(func=start)

sp_stop = sp.add_parser("stop", help=_("Stop Edubuntu server"))
sp_stop.set_defaults(func=stop)

sp_status = sp.add_parser("status", help=_("Query the status of "
                                           "Edubuntu server"))
sp_status.set_defaults(func=status)

args = parser.parse_args()

if not os.geteuid() == 0:
    print(_("You must be root to run this script. Try running: sudo %s" %
            (sys.argv[0])))
    sys.exit(1)

# Only import ipaddr and lxc now to avoid having to build-depend on them
import ipaddr
import lxc

if not hasattr(args, "func"):
    parser.print_help()
else:
    args.func()
