#!/usr/bin/env python
#

"""
gadmin: Perform server administration actions

Usage:
        gadmin -a sessions '.*/tty1'       # Python wildcard
        gadmin -a sessions '.*:'           # Python wildcard for all notebook sessions
        gadmin -a sessions '.*:Exercise2'  # Python wildcard for particular notebook sessions

        # Virtual lab dashboard
        gframe -f -t -p / -s /watch `gadmin -a sessions`

        # Click on session label ("terminal URL") in embedded window to open new full window)
        # Upload files using gupload
        # Download files by right clicking gls output
        # Open notebook file by clicking gls output
        # Create new notebook from menu
"""

from __future__ import absolute_import, print_function

import base64
import json
import os
import sys
import termios
import tty
import urllib

try:
    from collections import OrderedDict
except ImportError:
    from ordereddict import OrderedDict

try:
    import gterm
except ImportError:
    import graphterm.bin.gterm as gterm

usage = "usage: %prog action [args]"
parser = gterm.FormParser(usage=usage, title="Administer server: ", command="gadmin")
parser.add_argument(label="Argument 1: ", help="Argument 1")
parser.add_option("action", ("", "sessions", "mail"), short="a", help="Action (sessions|mail)")
parser.add_option("body", "", help="Body for mail message, with formatting for keywords: user, group, code, to, members")
parser.add_option("js", "", short="j", help="Javascript expression to be evaluated")
parser.add_option("execute", "", short="e", help="Shell command to be executed")
parser.add_option("autosave", False, help="Autosave notebooks")
parser.add_option("group", False, short="g", help="Group action")
parser.add_option("long", False, short="l", help="Long text output")
parser.add_option("subject", "", help="Subject for mail message")
parser.add_option("super_users", "", help="super users (comma-separated)")
parser.add_option("verbose", False, short="v", help="Verbose")
parser.add_option("text", False, short="t", help="Text only")

(options, args) = parser.parse_args()

if not gterm.Cookie or not sys.stdout.isatty():
    options.text = True

super_users = options.super_users.split(",") if options.super_users else []
action = options.action
if not args and not action:
    if options.text:
        sys.exit(parser.get_usage())
    gterm.write_form(parser.create_form(), command="gadmin")
    sys.exit(1)

home_root = "/home"
norm_users = []
if os.path.exists(home_root):
    for user in os.listdir(home_root):
        if not user[0].isalpha() or user in super_users:
            continue
        if os.path.exists( os.path.join(home_root, user, gterm.APP_DIRNAME) ):
            norm_users.append(user)

norm_users.sort()

user_props = OrderedDict()
for user in norm_users:
    gt_dir = os.path.join(home_root, user, gterm.APP_DIRNAME)
    try:
        with open(os.path.join(gt_dir, gterm.APP_AUTH_FILENAME, user)) as f:
            code = f.read().strip()
    except Exception:
        code = ""
    try:
        with open(os.path.join(gt_dir, gterm.APP_EMAIL_FILENAME)) as f:
            email = f.read().strip()
    except Exception:
        email = ""
    user_props[user] = {"code": code, "email": email}

if action == "mail":
    assert super_users, "No super user!"
    groups, membership = gterm.read_groups(super_users[0])
    mail_dict = OrderedDict()
    if options.group:
        group_names = groups.keys()
        group_names.sort()
        for group_name in group_names:
            members = groups[group_name]
            addrs = [user_props[user]["email"] for user in members if user_props.get(user) and user_props[user].get("email")]
            mail_dict[group_name] = {"user": "", "group": group_name, "to": ",".join(addrs),
                                     "code": "", "members": ",".join(members)}
    else:
        for user in norm_users:
            mail_dict[user] = {"user": user, "group": membership.get(user,""), "to": user_props[user]["email"],
                               "code": user_props[user]["code"], "members": ""}
    for key, val in mail_dict.iteritems():
        mail_body = options.body.replace("\\n","\n") % val
        if gterm.Cookie:
            mail_url = 'mailto:'+val["to"]+'?subject='+urllib.quote(options.subject)+'&body='+urllib.quote(mail_body)
            gterm.wrap_write('<p>Click <a href="'+mail_url+'">here</a> to email to '+key)
        else:
            print("\n" + key + ": " + options.subject)
            print("\n" + mail_body + "\n")
else:
    Headers = {"content_type": "text/plain"}
    Headers["x_gterm_response"] = "admin_command"
    Headers["x_gterm_parameters"] = {"action": options.action, "text_only": options.text, "long": options.long,
                                     "exec": options.execute,
                                     "js": options.js,
                                     "autosave": options.autosave,
                                     "args": args[0:]}

    gterm.wrap_write("", headers=Headers)
    (errmsg, headers, content) = gterm.receive_data()

    if not errmsg:
        errmsg = headers.get("x_gterm_error", "")

    if errmsg:
        sys.exit(errmsg)

    content_type = headers.get("content_type", "")
    if content_type == "text/html":
        gterm.wrap_write(content)
    else:
        sys.stdout.write(content)
    
