#
# -*- coding: utf-8 -*-

'''General things all querytool scripts need.
It also adjusts the sys path via biocase.adjustpath.py .
This module should be executed via execfile('ABS PATH TO HERE'). 
'''

############################################################################################################
#
#   IMPORTS
#
#===========================================================================================================

import cgitb; cgitb.enable()
import cgi, os, sys, string, time, random, Cookie
from types import *

import biocase.initlogs
biocase.initlogs.initWebappLogging()
import logging
log = logging.getLogger("webapp.cfgtool")

import biocase.configuration
from biocase.wrapper.errorclasses import *
from biocase                   import __version__
from biocase.datasources       import Datasource
from biocase.tools.htmltools   import ankerClass, escapeHtml, getDropDownHtml, getDropDownOptionHtml
from biocase.tools.templating  import PageMacro, genOptionList
from biocase.tools.various_functions import getEncodingList
from biocase.tools.caching  import getCachedFilename
from biocase.wrapper.dbmod import getDBMSList




_COOKIE = Cookie.SimpleCookie()
_ADMIN_KEY = '__keyADMIN1973__'

############################################################################################################
#
#   GENERAL FUNCTIONS
#
#===========================================================================================================
def printOverHTTP(templ):
    print 'Content-Type: text/html; charset=utf-8'
    print _COOKIE
    print
    print str(templ)


# ------------------------------------------------------------------------------------
def authenticationForm(script=None, dsa=None):
    if script is None:
        script = os.environ.get('SCRIPT_NAME', '')
    tmpl = PageMacro('Content', PageMacro.DELMODE)
    tmpl.load('Content', os.path.join(cfg.wwwLocator, 'configtool', '_password.html'))
    if dsa is not None:
        tmpl['dsa'] = dsa
    tmpl['script'] = script
    # print HTML !
    printOverHTTP(tmpl)
    # stop script
    sys.exit()

#
def dsa2Cookie(dsa):
    if dsa is None:
        dsa=_ADMIN_KEY
    return "org.biocase.bps2.%s"%(dsa)
    
def authorize(form, dsa=None):
    '''If dsa=None onl the system admin password can get authorisation'''
    dsaCookieName=dsa2Cookie(dsa)
    adminCookieName=dsa2Cookie(_ADMIN_KEY)
    # load received http cookie
    if os.environ.has_key('HTTP_COOKIE'):
        _COOKIE.load(os.environ['HTTP_COOKIE'])
        log.debug("Cookie recieved: %s"%str(_COOKIE))
    # check if authorised to edit this DSA
    tnow=time.time()
    if _COOKIE.has_key(dsaCookieName) and  tnow-float(_COOKIE[dsaCookieName].value) < cfg.login.expire:
        log.debug("Already logged in dsa %s."%(dsa))
        log.debug("AuthCookie expires in: %s"%str(cfg.login.expire-tnow+float(_COOKIE[dsaCookieName].value)))
        return True
    elif _COOKIE.has_key(adminCookieName) and  tnow-float(_COOKIE[adminCookieName].value) < cfg.login.expire:
        log.debug("Already logged in as admin.")
        log.debug("AuthCookie expires in: %s"%str(cfg.login.expire-tnow+float(_COOKIE[adminCookieName].value)))
        return True
    # check login
    elif login(form, dsa):
        # set new cookie
        _COOKIE[dsaCookieName] = tnow
        _COOKIE[dsaCookieName]['max-age'] = cfg.login.expire  # expire in 1 hour (=60*60 seconds)
        return True
    # present login form
    authenticationForm(dsa=dsa)
    return False
    
def login(form, dsa):
    '''Add a 30 minutes login to the users cookie based session for the given dsa or the system admin if dsa=None'''
    log.info("Logging into dsa %s via password"%dsa)
    clearPasswd = form.getfirst('passwd', None)
    if clearPasswd is None or clearPasswd=="":
        log.debug("No password provided")
        return False
    elif clearPasswd == cfg.server.adminpassword:
        log.debug("Authenticated as system admin user")
        return True
    elif dsa is not None:
        dsaObj = Datasource(name=dsa)
        try:
            psfObj = dsaObj.getPSFObj()
        except IOError:
            log.warn("Cant log into dsa %s. It doesnt exist!"%dsa)
            return False
        if clearPasswd == psfObj.adminpassword:
            log.debug("Authenticated as dsa=%s admin user"%dsa)
            return True
    log.debug("Authentication failed for dsa %s"%dsa)
    return False
    



# ------------------------------------------------------------------------------------
def getTmpCmFilename(cmFile):
    return getCachedFilename(cmFile+"_cfgtool.tmp")
    
def readTmpCmFile(cmfObj, cmFile, psfObj):
    cmFilePickle = getTmpCmFilename(cmFile)
    log.debug("Cached pickle file is %s"%(cmFilePickle))
    if os.path.isfile(cmFilePickle):
        log.debug("Read existing cached pickle file %s"%(cmFilePickle))
        isGood = cmfObj.__unpickle__(filename=cmFilePickle)
        if not isGood:
            log.debug("Failed to read cached pickle file. Read original CMF xml-file instead.")
            readOriginalCmFile(cmfObj, cmFile=cmFile, psfObj=psfObj)
    else:
        readOriginalCmFile(cmfObj, cmFile=cmFile, psfObj=psfObj)
    log.debug("altRootTableAliasSPICE = %s" % unicode(cmfObj.altRootTableAliasSPICE))
    return cmFilePickle

def readOriginalCmFile(cmfObj, psfObj, cmFile=None):
    global cfg
    log.debug("Read original CMF xml-file %s"%(cmFile))
    try:
        cmfObj.loadCMFdata( filename=cmFile, psfObj=psfObj, pickle=True )
    except TableConfigError:
        log.warn("CMF file %s and the PSF dont match. Table config errors."%(cmFile))
    
    
    
############################################################################################################
#
#   MAIN
#
#===========================================================================================================


# get global project configurations
cfg = biocase.configuration.Cfg()
# LOGGING
log.info("--- NEW CONFIGTOOL REQUEST ---")
# dirs used with the configtool
configDir   = os.path.join(cfg.configurationLocator, 'configtool') # configtool config dir
templateDir = os.path.join(cfg.wwwLocator, 'configtool') 

#
# ANALYZE CGI ENVIRONMENT
#
form = cgi.FieldStorage()
log.debug("CGI FORM VALUES: %s"%str([(k,form[k]) for k in form.keys()]))

# dsa
dsa = form.getfirst('dsa',None)
if dsa is not None:
    dsaObj = Datasource(name=dsa)
else:
    dsaObj = None
log.debug("DSA=%s"%str(dsa))
    
# schema
schema = form.getfirst('schema', None)
log.debug("Schema=%s"%str(schema))
    
# action
action = form.getfirst('action', form.getfirst('action_override', None))
if action is not None:
    action = action.lower()
log.debug("Action=%s"%str(action))
