#!/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
"""

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

import 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")
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.Lterm_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":
    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.Lterm_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)
    
