# coding: utf-8
u"""
GIS failu web serveris
"""
prog = "web-server"
version="%(prog)s v0.1"
epilog = "(c)Ivars 2017"

import sys, os, os.path, argparse
import re,cgi, urllib, json
import datetime,time

from zope.interface import implements
from twisted.internet import reactor,defer, threads, task
from twisted.web import server, resource, http, error, util
from twisted.python import log,logfile
from twisted.web import static

xset = lambda x,y: x if x else y

options = []

class ResponseFile(static.File):

    def __init__(self, path):
        static.File.__init__(self, path)

    def render_GET(self, request):
        #request.setHeader('Content-Disposition', ['attachment ; filename="tick_db_export.csv"'])
        return static.File.render_GET(self, request)

def parse_arguments(argv):
    "Parse command line arguments"
    parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description =__doc__,epilog=epilog, version=version, prog=prog)
    parser.add_argument("-p", "--port",  type=int, help="web server port")
    parser.add_argument("--debug", action="store_true", dest="debug", default=False, help="print debug info")
    return parser.parse_args(argv), parser

#import config   # get parameters from ini file
def main(argv):

    # get global parameters from command line arguments and ini file
    global options
    options,parser = parse_arguments(argv[1:])

    #log.startLogging(logfile.DailyLogFile.fromFullPath("logs\\gis-faili.log"))
    log.startLogging(sys.stdout)

    # root = MyFile(base)               # no directory browsing
    #root = Root()
    #root = static.File("/")
    #root = ResponseFile(".")
    root = urlproxy.URLProxy()

    # Start web server
    reactor.listenTCP(8000, server.Site(root))
    reactor.run()


class ResourceThread(resource.Resource):
    "Resource subclass, which renders request in thread. Redefine 'process' "
    def render_GET(self, request):
        d = threads.deferToThread(self.process,request)
        d.addCallback(self._cb,request)
        d.addErrback(self._eb,request)
        request.notifyFinish().addErrback(self._connection_lost, d)
        return server.NOT_DONE_YET

    def render_POST(self, request):
        d = threads.deferToThread(self.process,request)
        d.addCallback(self._cb,request)
        d.addErrback(self._eb,request)
        request.notifyFinish().addErrback(self._connection_lost, d)
        return server.NOT_DONE_YET

    def _cb(self, result, request):
        "Callback function"
        request.write(result)
        request.finish()

    def _eb(self, failure, request):
        "Errorback function"
        #err = failure.trap(defer.CancelledError)
        if failure == defer.CancelledError:
            log.msg("Connection canceled")
            return None
        else:
            #log.err(failure)
            failure.printTraceback()
            body = resource.ErrorPage(http.INTERNAL_SERVER_ERROR,
                             "Internal errror, see log file for details","").render(request)
        request.write(body)
        request.finish()

    def _connection_lost(self,err,d):
        d.cancel()

    def process(self,request):
        "Process request. Shoud be redefined"
        return "No process method defined"

    def get_req(self,request,exclude=[]):
        "Return request parameters as Rec() object in utf8, add user. Exclude parameters listed in exclude"
        req = Rec()
        for k,v in request.args.iteritems():
            if k in exclude:
                continue
            req[k] = ",".join(v)
            req[k] = req[k].decode("utf8")
        req.user = request.getUser()
        return req


######### http commands handlers ####################
class Root(ResourceThread):
    "Server root"
    isLeaf = True

    def process(self,request):
        "Apstrada pieprasijumu"
        req = self.get_req(request)
        request.responseHeaders.setRawHeaders("Content-type",['text/html; charset=utf-8'])
        html = u"Response text".encode("utf8")
        return html
        #self.file = static.File("./aaa.mp4")
        #request.uri = "/aaa.mp4"
        #return self.file.render_GET(request)


import UserDict
class Rec(UserDict.DictMixin):
    "Dict like class allowing a.x instead of a['x']"
    def __init__(self, dict=None, **kwargs):
        self.__dict__ = {}
        if dict is not None:
            self.update(dict)
        if len(kwargs):
            self.update(kwargs)
    def __setitem__(self, name, value): setattr(self, name, value)
    def __getitem__(self, name): return getattr(self,name,None)
    def __getattr__(self,key): return None
    def has_key(self,key): return True if self.__dict__.has_key(key) else False
    def keys(self): return list(self.__dict__)

if __name__ == "__main__":
    sys.exit(main(sys.argv))
