#!/net/dblocal/src/python/python3/bin/python3

#### Define eprint() to print to stderr
from __future__ import print_function
import sys
def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

#### Import some standard libraries
import os
import argparse
import os.path
import timeit
import re
import json

#### Set the base of where the SpectralLibraries Python libraries are
basedir = "/net/dblocal/data/SpectralLibraries/python/devED/SpectralLibraries"
#basedir = os.path.dirname(os.path.abspath(__file__))+"/.."

#### Import SpectralLibrary Python modules
sys.path.append(basedir+"/lib")
from SpectrumLibraryCollection import SpectrumLibraryCollection
from SpectrumLibrary import SpectrumLibrary
from Spectrum import Spectrum
from universal_spectrum_identifier import UniversalSpectrumIdentifier


#### Main execution function
def main():

    #### Parse command-line arguments
    argparser = argparse.ArgumentParser(description='Reads one spectrum from a file and prints to stdout')
    argparser.add_argument('--library_file', action='store', help="Name of the library file to access")
    argparser.add_argument('--index_number', action='store', help="Index number of the spectrum to display")
    argparser.add_argument('--usi', action='store', help="Universal Spectrum Identifier of the spectrum to display")
    argparser.add_argument('--output_format', action='store', default='text', help="Format use when writing the spectrum (one of 'text', 'json', 'msp')")
    argparser.add_argument('--version', action='version', version='%(prog)s 0.5')
    params = argparser.parse_args()
    response = { 'state': 'OK', 'status': 200, 'title': 'OK', 'detail': 'Function completed normally' }
    mode = 'CLI'

    #### CGI debugging stuff
    #print("Content-type: text/plain\n")
    #print(os.environ)
    #print(f"INFO: QUERY_STRING: {os.environ['QUERY_STRING']}")

    #### If we got here through CGI
    if "REQUEST_URI" in os.environ:
        mode = 'HTTP'

        #### Set the output_format to json if the HTTP_REQUEST_TYPE was set to json
        if "HTTP_REQUEST_TYPE" in os.environ and os.environ["HTTP_REQUEST_TYPE"] == "application/json":
            params.output_format = 'json'


    #### If there is a query string
    if "QUERY_STRING" in os.environ and os.environ["QUERY_STRING"] > "":

        #### Parse out the CGI parameters and put in place of command-line arguments
        keyvaluepairs = re.split("&", os.environ["QUERY_STRING"])
        for keyvaluepair in keyvaluepairs:
            key, value = re.split("=", keyvaluepair, 1)
            if key == "usi":
                params.usi = value
            elif key == "output_format":
                params.output_format = value
            else:
                response = { 'state': 'ERROR', 'status': 460, 'title': 'Unrecognized Parameter', 'detail': f"Unrecognized parameter: {keyvaluepair}" }
                send_response(response, output_format=params.output_format, mode=mode)
                return()

    library_file = params.library_file
    index_number = params.index_number

    #### Ensure that either a USI or a library_file and index_number was passed
    if params.usi is None or params.usi == "":
        if params.library_file is None or params.library_file == "":
            response = { 'state': 'ERROR', 'status': 461, 'title': 'Insufficient Parameters', 'detail': "Parameter usi or library_file must be provided. See --help for more information" }
            send_response(response, output_format=params.output_format, mode=mode)
            return()

        if params.index_number is None or params.index_number == "":
            response = { 'state': 'ERROR', 'status': 461, 'title': 'Insufficient Parameters', 'detail': "Parameter usi or index_number must be provided. See --help for more information" }
            send_response(response, output_format=params.output_format, mode=mode)
            return()

    #### If there was a USI, then parse it
    else:
        usi = UniversalSpectrumIdentifier(params.usi)
        if not usi.is_valid:
            response = { 'state': 'ERROR', 'status': 463, 'title': usi.error_code, 'detail': usi.error_message }
            send_response(response, output_format=params.output_format, mode=mode)
            return()
        if usi.collection_identifier.startswith("PXL"):
            spec_lib_collection = SpectrumLibraryCollection(basedir + "/spectralLibraries/SpectrumLibraryCollection.sqlite")
            #print(f"Looking up library for {usi.collection_identifier}")
            try:
                library = spec_lib_collection.get_library(identifier=usi.collection_identifier, version=usi.ms_run_name)
            except Exception as error:
                response = { 'state': 'ERROR', 'status': 462, 'title': 'Other Error', 'detail': error }
                send_response(response, output_format=params.output_format, mode=mode)
                return()
            #print("Found record: " + "\t".join([str(library.library_record_id),library.id_name,library.version,library.original_name]))
            library_file = basedir + "/spectralLibraries/" + library.original_name
            index_number = usi.index

    if not os.path.isfile(library_file):
        eprint(f"ERROR: File '{library_file}' not found or not a file")
        return()

    spectrum_library = SpectrumLibrary()
    spectrum_library.filename = library_file

    spectrum_buffer = spectrum_library.get_spectrum(spectrum_index_number=index_number)
    spectrum = Spectrum()
    spectrum.parse(spectrum_buffer, spectrum_index=index_number)
    buffer = spectrum.write(format=params.output_format)
    send_response(response, output_format=params.output_format, mode=mode)
    print(buffer)

    return()


############################################################################
#### Write out the current status in the correct format
def send_response(response, output_format="text", mode='CLI'):

    if mode == 'HTTP':
        if response['state'] == 'OK':
            pass
        else:
            print("Status: " + str(response['status']))

        #### Start the HTTP output
        if output_format == 'json':
           print("Content-type: application/json\n")
        else:
           print("Content-type: text/plain\n")

        #### If this is an error, show the error information
        if response['state'] != 'OK':
            if output_format == 'json':
                response['type'] = 'about:blank'
                print(json.dumps(response,sort_keys=True,indent=2))
            else:
                for key in response:
                    print(f"{key}: " + str(response[key]))

    else:
        if response['status'] == 'OK':
            print("(OK)")
        else:
            if output_format == 'json':
                print(json.dumps(response,sort_keys=True,indent=2))
            else:
                for key in response:
                    print(f"{key}: " + str(response[key]))


#### When executed directly, run the main() function
if __name__ == "__main__": main()
