from fastapi import FastAPI, Request, Query, Response
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from common.query_parser import QueryParser
from common.tsakorpus_query_parser import TsakorpusQueryParser
from common.tsakorpus_response_parser import TsakorpusResponseParser
from common.enums import *
from common.diagnostics import Diagnostic
from common.config import ResourceConfig, read_configs
import json
import os
import re
import uvicorn

app = FastAPI()
app.mount('/static', StaticFiles(directory='static'), name='static')
templates = Jinja2Templates(directory='static')

app.qp = QueryParser()
app.qp_tsakorpus = TsakorpusQueryParser()
app.rp_tsakorpus = TsakorpusResponseParser()
app.configs = read_configs()


@app.get('/')
def root():
    return {"message": "Hello World"}


@app.get('/fcs-endpoint/{corpusID}')
def endpoint(
        request: Request,
        corpusID: str,
        operation: Operation = Operation.explain,
        version: SRUVersion = SRUVersion.v2_0,
        queryType: QueryType = QueryType.fcs,
        query: str = '',
        xFcsEndpointDescription: str = Query(
            default='',
            alias='x-fcs-endpoint-description'
        ),
        xFcsContext: str = Query(
            default='',
            alias='x-fcs-context'
        ),
        xFcsDataviews: str = Query(
            default='',
            alias='x-fcs-dataviews'
        ),
        xFcsRewritesAllowed: str = Query(
            default='',
            alias='x-fcs-rewrites-allowed'
        )
        ):
    if corpusID not in app.configs:
        message = 'No corpus with this ID (' + corpusID +') is served by this Endpoint. ' \
                  'Valid corpus IDs are: ' + '; '.join(cID for cID in sorted(app.configs)) + '.'
        diagBody = str(Diagnostic(DiagnosticTypes.sru, 235,
                       message=message))  # "Database does not exist"
        return Response(content=diagBody, media_type='application/xml')
    config = app.configs[corpusID]
    diagnostics = app.qp.validate_query(operation, version, queryType, query,
                                        xFcsEndpointDescription, xFcsContext,
                                        xFcsDataviews, xFcsRewritesAllowed)
    if any(d.is_fatal() for d in diagnostics):
        return '\n'.join(str(d) for d in diagnostics)

    if operation == Operation.searchRetrieve:
        if config.platform == CorpPlatform.tsakorpus:
            try:
                strGetParams = app.qp_tsakorpus.translate_fcsql(query, config)
                print(strGetParams)
                res = app.qp_tsakorpus.send_query(strGetParams, config)
            except Diagnostic as diag:
                print('diag', str(diag))
                return Response(content=str(diag), media_type='application/xml')
            records, nHits = app.rp_tsakorpus.parse(res, config)
            records = [r.as_dict() for r in records]
            return templates.TemplateResponse('search_retrieve_response.xml',
                                              {
                                                  'request': request,
                                                  'n_hits': nHits,
                                                  'records': records
                                              })
                                              # media_type='application/xml')
            # return str(res)

    return {'operation': operation, 'version': version}


if __name__ == '__main__':
    uvicorn.run(
        'main:app',
        host='0.0.0.0',
        port=5000,
        reload=True
    )