import tornado.ioloop
import tornado.web
import tarfile
import json
from config import IMPORT_AUDIT, IMPORT_FINAL, MANIFEST
from sublogin import login
from submove import process_file_import
from functools import wraps
from StringIO import StringIO

import os
WORKING_DIR = os.path.dirname(os.path.abspath(__file__))
COOKIE_SECRET = "F+ek4AWESWewGryPRbzq5aSHR1uRD0/ItZenLimCkGI="
STATIC_DIR = os.path.join(WORKING_DIR,"static")
TEMPLATE_DIR = os.path.join(WORKING_DIR,"templates")
TORNADO_PORT = "8888"

class BaseHandler(tornado.web.RequestHandler):
  def get_login_url(self):
    return u"/login"

  def get_current_user(self):
    user_json = self.get_secure_cookie("user")
    if user_json:
      return tornado.escape.json_decode(user_json)
    else:
      return None

  def get_admin_status(self):
    admin_json = self.get_secure_cookie("admin")
    if admin_json:
      return tornado.escape.json_decode(admin_json)
    else:
      return None

  def render(self, template, **kwargs):
    kwargs['admin'] = self.get_admin_status()
    super(BaseHandler, self).render(template, **kwargs)

class LoginHandler(BaseHandler):
  def get(self):
    self.render('login.html') 
  
  def post(self):
    username = self.get_argument("username", "")
    password = self.get_argument("password", "")
    status, error =  login(username, password)
    if status:
      adminstatus = error #Yes, ghetto
      self.set_current_user(username)
      self.set_admin_status(adminstatus)
      self.redirect(self.get_argument("next",u"/"))
    else:
      self.render("login.html", errormsg=error)

  def set_current_user(self, user):
    if user:
      self.set_secure_cookie("user", tornado.escape.json_encode(user))
    else:
      self.clear_cookie("user")

  def set_admin_status(self, admin):
    if admin:
      self.set_secure_cookie("admin", tornado.escape.json_encode(admin))
    else:
      self.clear_cookie("admin")

class LogoutHandler(BaseHandler):
  def get(self):
    self.clear_cookie("user")
    self.clear_cookie("admin")
    self.redirect(u"/login")

class UploadHandler(BaseHandler):
  @tornado.web.authenticated
  def get(self):
    self.render("index.html")
  
  @tornado.web.authenticated
  def post(self):
    if self.request.files:
      files = []
      for f in self.request.files.itervalues():
          files.append((f[0]['filename'], f[0]['body']))
      process_file_import(self.current_user, files)

def is_admin(method):
  @wraps(method)
  def wrapper(self, *args, **kwargs):
    if self.get_admin_status():
      return method(self, *args, **kwargs)
    else:
      self.redirect(u"/") 
  return wrapper

class AdminHandler(BaseHandler):
  @tornado.web.authenticated
  @is_admin
  def get(self):
    #if self.request.headers.get('X-Requested-With') == "XMLHttpRequest":
    audit_tar = False
    items = []
    for filename in os.listdir(IMPORT_AUDIT):
      try: audit_tar = tarfile.open(os.path.join(IMPORT_AUDIT,filename), mode = "r:gz")
      except: pass
      if audit_tar:
        if MANIFEST in audit_tar.getnames():
          items.append(json.loads(audit_tar.extractfile(MANIFEST).read()))
          
    self.render("admin.html", items=items)

  @tornado.web.authenticated
  @is_admin
  def post(self):
    def admin_response(audit_id,result_type,result):
      self.write(json.dumps({"id":audit_id, "result_type": result_type, "result": result}))
    
    if self.request.headers.get("Content-Type").startswith("application/json"):
      self.json_args = json.loads(self.request.body)
      audit_id = self.json_args['id']
      audit_file = audit_id+".tar.gz"
      audit_approve = self.json_args['approve']
      if audit_file in os.listdir(IMPORT_AUDIT):
        if audit_approve:
          try:
            os.rename(os.path.join(IMPORT_AUDIT,audit_file), os.path.join(IMPORT_FINAL,audit_file))      
            admin_response(audit_id, "success", "Transfer Approved")
          except:
            admin_response(audit_id, "error", "Transfer Approval Failed")
        else:
          try:
            os.remove(os.path.join(IMPORT_AUDIT,audit_file))
            admin_response(audit_id, "success", "Transfer Destruction Success")
          except:
            admin_response(audit_id, "success", "Transfer Destruction Failed")
      else:
        self.write(json.dumps({"id":audit_id, "result_type": "error", "result":"Invalid ID, File not found"}))
    else:
	pass


handlers = [
  (r"/", UploadHandler),
  (r"/admin", AdminHandler),
  (r"/login", LoginHandler),
  (r"/logout", LogoutHandler),
]  

settings = {
  "cookie_secret": COOKIE_SECRET,
  "static_path": STATIC_DIR,
  "template_path": TEMPLATE_DIR,
}

application = tornado.web.Application(handlers, **settings )

if __name__ == "__main__":
  application.listen(TORNADO_PORT)
  tornado.ioloop.IOLoop.instance().start()

