#!c:\Program Files\Python39\python.exe
# -*- coding: UTF-8 -*-

'''
$RCSfile: details.py,v $
$Revision$
$Author: markus $
$Date$
The BioCASE querytool
'''

import os, sys, urllib.request, urllib.parse, ssl, json, datetime, traceback

# ***** include the biocase.lib directory in the python sys path for importing *****
exec(open(os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir, 'lib', 'biocase', 'adjustpath.py'))).read())
# exec(compile(open( os.path.abspath( os.path.join( os.path.dirname( __file__ ), os.pardir, os.pardir, 'lib', 'biocase', 'appinit.py' ) ), "rb").read(), os.path.abspath( os.path.join( os.path.dirname( __file__ ), os.pardir, os.pardir, 'lib', 'biocase', 'appinit.py' ) ), 'exec'))

# import pydevd; pydevd.settrace();
from biocase.tools.templating import PageMacro
import biocase.configuration
from biocase.querytool.general import form, skinDir, schemaObj, dsa, schema, wrapper_url, printOverHTTP, logDiagnostics, transformXML
from biocase.querytool.filter import AndClass, EqualsClass, Concept
from biocase.querytool.querydispatcher import QueryDispatcher, WrapperError
from biocase.querytool.querygenerator import QueryGenerator

import logging
log = logging.getLogger("querytool.details")

# Load BioCASe cfg
cfg = biocase.configuration.Cfg()

tmpl = PageMacro('Content', PageMacro.DELMODE)
tmpl.load('Content', os.path.join(skinDir, 'details.html'))

# which detail do we need to create?
detail = form['detail'].value
detailObj = schemaObj.details[detail]

log.info("PREFS DETAILS OBJ: %s" % detailObj)

# parameters for the AnnoSys button
annosys = {'providerURL': wrapper_url, 'formatURI': schema}
# build a new filter object from form values of the record identifiers.
# First create list of needed COP objects
filterObj = AndClass()
for para, recID in list(detailObj.recID.items()):
    # create an equals cop for every recID, store params for annoSys
    if form.getfirst(para, None) is not None:
        conObj = Concept(NS=schema, path=recID.path, label=para)
        cop = EqualsClass(conObj, form.getfirst(para, None))
        annosys[para.replace("inst", "institution").replace("col", "source").replace("cat", "unitID")] = form.getfirst(para, None)
        filterObj.addOperand(cop)
log.info("FILTER OBJ: %s" % filterObj)

# generate the protocol
QG = QueryGenerator()

protocolXML = QG.getSearchProtocol(NS=schemaObj.NS, respNS=schemaObj.NS, count=False, filterObj=filterObj, destination=wrapper_url)
log.info("QUERY PROTOCOL CREATED:\n%s" % protocolXML)

# query the wrapper
QD = QueryDispatcher()
try:
    recStatus = QD.sendQuery(wrapper_url, protocolXML)
except WrapperError as e:
    # wrapper error occured !!!
    tmpl = PageMacro('Content', PageMacro.DELMODE)
    tmpl.load('Content', '_error.html')
    tmpl['dsa'] = dsa
    tmpl['ErrorMessage'] = e.msg
    printOverHTTP(tmpl)
    sys.exit()

content = QD.getContent()
logDiagnostics(QD.getDiagnostics())

if content is None:
    # no wrapper results found
    log.info("NO CONTENT ROOT FOUND.")
    stylesheetResult = "<strong>%s</strong>" % detailObj.notAvailableMessage
else:
    if log.isEnabledFor(logging.DEBUG):
        log.debug("XML CONTENT TO BE TRANSFORMED::::::::::::::::::")
        log.debug(content)
    # apply stylesheet
    stylesheetResult = transformXML(content, os.path.join(skinDir, detailObj.stylesheet))
    if log.isEnabledFor(logging.DEBUG):
        log.debug("XSLT TRANSFORMATION RESULT:::::::::::::::::")
        log.debug(stylesheetResult)

# Get list of annotations, based on triple ID
# Plus create annotation link
if cfg.server.annosys_baseurl and cfg.server.annosys_baseurl != '0':
    base_url = cfg.server.annosys_baseurl
    if cfg.server.annosys_baseurl.endswith('/'):
        base_url = cfg.server.annosys_baseurl[:-1]
    else:
        base_url = cfg.server.annosys_baseurl
    annosys_create = '%s/AnnoSys?protocolURI=http://www.biocase.org/schemas/protocol/1.3&%s' % (base_url, urllib.parse.urlencode(annosys))
    try:
        anno_listurl = base_url + urllib.parse.quote('/services/records/%s/%s/%s/annotations' % (annosys['institution'], annosys['source'], annosys['unitID']))
        log.debug("Loading annotations from URL %s" % anno_listurl)
        try:
            ws = urllib.request.urlopen(anno_listurl)
        except:
            # This is a fix for a ssl handshake error on certain installations (e.g. BGBM's installation in Windows Server)
            # Set the SSL context explicitly
            ws = urllib.request.urlopen(anno_listurl, context=ssl.SSLContext(ssl.PROTOCOL_TLSv1_2))
        resp = json.load(ws)
        anno_list = ''
        for anno in resp['annotations']:
            anno_list += '<br><a href="%s/AnnoSys?repositoryURI=%s" target="_blank">%s</a> by %s (created %s)' % (
                base_url, anno['repositoryURI'], anno['motivation'], anno['annotator'], datetime.datetime.fromtimestamp(anno['time'] / 1000))
        annosys_list_html = '<strong>%i annotation(s) for this record:</strong>' % resp['size'] + anno_list if anno_list else 'No annotations found for this record.'
    except Exception:
        msg = traceback.format_exc().replace('"', "'").replace("\\", "/")
        annosys_list_html = '<span title="%s"><i>ERROR: Annotation list could not be retrieved (hover over this text for details).</i></span>' % msg
    finally:
        # Construct AnnoSys output
        # (This is done not in the cgi script to allow empty output if AnnoSys is disabled)
        tmpl['annosys'] = '''
            <p><img src="../resources/images/annosys.png" alt="AnnoSys" border="0" align="right" height="50"></p>
            <p>%s</p>
            <p><a href="%s" target="_blank">Create an annotation with AnnoSys!</a></p>''' % (annosys_list_html, annosys_create)
else:
    tmpl['annosys'] = '<!-- AnnoSys disabled in configuration -->'

# update template
tmpl['dsa'] = dsa
tmpl['schema'] = schema
tmpl['filter'] = str(filterObj)
tmpl['filter_display'] = str(filterObj).replace('_', ' ')
tmpl['XSL'] = str(stylesheetResult)
if wrapper_url is not None:
    tmpl['wrapper_url'] = wrapper_url

#
# print HTML !
#
printOverHTTP(tmpl)