from twisted.web import resource, static
import cgi, logging
from zope.interface import implements
from twisted.cred import portal, checkers, credentials
from nevow import inevow, rend, tags, guard, loaders
import auth
import os, sys
from twisted.python import reflect


#      request = inevow.IRequest(ctx)
#      if request.method == 'POST':
#         log.debug("POST TelContent")
#         try:
#            if request.args["Aggiorna"][0] == 'Aggiorna':


log = logging.getLogger("HTTPTunnel")

curdir=os.path.abspath(os.path.dirname(sys.argv[0]))

class HTTPTunnelServer(rend.Page):

   addSlash = True
   clients =  {}


   def __init__(self, command):
      log.debug("Connection to Tunnel")
      self.command = command
      self.curdir=os.path.abspath(os.path.dirname(sys.argv[0]))
      rend.Page.__init__(self)

   def renderHTTP(self, ctx):
      log.debug('Called /')
      return 'What?'

   def removeClient(self, conid):
      try:
         del self.clients[conid]
      except:
         pass

   def child_START(self, ctx):
      ret = 'NOPERM'
      # generiamo una sessione che usiamo come indice per le connessioni
      sess = inevow.ISession(ctx)
      self.sess = sess
      log.debug('Sessione Web START: '+str(sess.uid)+str(sess))
      if sess not in self.clients.keys():
         ret = 'OK:'+str(sess.uid)
         # occorre mettere un timeout, se non viene richiamata la GET o la PUT
         # per piu' di tot tempo, la chiave in clients va cancellata!
         # ( un timer o lasciamo fare al client protocol? )
         self.clients[sess.uid] = {}
         # bisogna poi creare un hash sha1 o simili da usare come chiave 
         # AES256 per crittografare il traffico, chiave che poi viene usata
         # ANCHE per decrittare e controllare le PUT, oltre che per
         # crittografare le GET
      return ret

   def child_PUT(self, ctx):
      ret = 'NOPERM'
      conid = 'NONE'
      request = inevow.IRequest(ctx)
      if request.method == 'POST':
         if 'conid' in request.args.keys() and 'data' in request.args.keys():
            try:
               if request.args['conid'][0] in self.clients.keys():
                  data=request.args['data'][0]
                  conid=request.args['conid'][0]
                  # a questo punto prendiamo la PUT in base64 e prendiamo la sua chiave
                  # che sara' nel clients in base al conid, decrittiamo il
                  # data dopo averlo riportato all'origine dal base64,
                  # che sara' del tipo "conid:blablah"
                  # tutto al client proto
            except:
               pass
      log.debug('Sessione Web PUT: '+conid)
      return ret

   def child_GET(self, ctx):
      ret = 'NOPERM'
      client  = 'NONE'
      request = inevow.IRequest(ctx)
      if request.method == 'GET':
         if len(request.uri.split('?', 2)) > 1:
            if request.uri.split('?', 2)[1] in self.clients.keys():
               client = request.uri.split('?', 2)[1]
               ret = client
               # qui dobbiamo aprire la sessione del protocol, prendiamo tutte
               # le write che avvengono e le crittiamo con la chiave nel
               # clients sul conid che e' qui chiamato client, le passiamo in
               # base64, e le restituiamo all'utente. Tutto questo in un while
               # che verifica se la connessione nel protocol e' online, e con
               # un mime-type che ci permetta di mantenere la connessione
               # sempre up. Se usciamo dal while, invece, dobbiamo impostare
               # la connessione a down con tutto cio' che ne consegue
               #
               # NOTA: come facciamo a ritornare dati al client prima di
               # arrivare al return della GET? si puo' spezzettare il ritorno
               # senza per questo avere la return?

      log.debug('Sessione Web GET: '+client)
      return ret
