import os
from sys import stderr
import subprocess
from subprocess import Popen
import json

JAVA_BIN_PATH = 'java'
tmp_folder = '/tmp/ollie/'
if not os.path.exists(tmp_folder):
    os.makedirs(tmp_folder)
tmp_output_folder = tmp_folder+"output/"
if not os.path.exists(tmp_output_folder):
    os.makedirs(tmp_output_folder)



def __texts_to_files(texts,fileNameHeadder=""):
    full_tmp_file_names = []
    count = 0
    for text in texts:
        tmp_filename = fileNameHeadder+str(count) + '.txt'
        full_tmp_filename = '{}/{}'.format(tmp_folder, tmp_filename).replace('//', '/')
        with open(full_tmp_filename, 'w') as f:
            f.write(text)
        full_tmp_file_names.append(full_tmp_filename)
        count += 1
    return full_tmp_file_names

def ollie_single(text,fileNameHeadder="", verbose=False):
    if os.path.isfile(text):
        full_tmp_filename = text
    else:
        full_tmp_filename = __texts_to_files([text],fileNameHeadder=fileNameHeadder)[0]
    results = __ollie(full_tmp_filename) #No need to pass the headder as the output name is generated by input name. So the headder gets automatically included
    return results

def ollie_single_simple(text,fileNameHeadder="", verbose=False):
    triples,_=ollie_single(text=text,fileNameHeadder=fileNameHeadder, verbose=verbose)
    return triples

def __process(lines):
    #print(lines)
    entryDict={}
    entry=""
    values={}
    simpleTripleList=[]
    for line in lines:
        if line=="\n":
            entryDict[entry]=values #finish the previous entry

            entry = "" #going to start a new entry
            values = {} #ditto
        else:
            line=line.replace("\n","")
            if len(entry)==0: #this is a new entry
                entry=line #Add the original sentence
                values = {} #Reset the values dictionary
            else:
                if line!="No extractions found.":
                    conf,triple=line.split(":",1)
                    triple=triple.strip()
                    #triple=triple.split(";")
                    #print(triple)
                    object,relation,subject=triple.split(";") #triple[0],triple[1],triple[2]

                    object=object.replace("(","")

                    condition =""
                    if "[enabler=" in subject:
                        subject,condition=subject.split("[enabler=")
                        condition=condition[:-1]
                        condition="enabler="+condition
                    elif "[attrib=" in subject:
                        subject,condition=subject.split("[attrib=")
                        condition=condition[:-1]
                        condition = "attrib=" + condition

                    subject=subject.replace(")","")

                    object=object.strip()
                    relation=relation.strip()
                    subject=subject.strip()

                    triple=(object,relation,subject)
                    values[triple]=(float(conf),condition)
                    simpleTripleList.append(list(triple))

    entryDict[entry] = values  # Add the last entry


    return (simpleTripleList,entryDict)

def __ollie(input_filename):
    input_filename = input_filename.replace(',', ' ')

    new_filename = ''
    for filename in input_filename.split():
        if filename.startswith('/'):  # absolute path.
            new_filename += '{} '.format(filename)
        else:
            new_filename += '../{} '.format(filename)
    newOutputName=new_filename.replace(tmp_folder,tmp_output_folder)

    absolute_path_to_script = os.path.dirname(os.path.realpath(__file__)) + '/'
    command = 'cd {};'.format(absolute_path_to_script)
    command += '{} -mx4g -jar ollie-app-latest.jar --split {} --output {}'.format(JAVA_BIN_PATH, new_filename, newOutputName)
    print(command)
    java_process = Popen(command, stdout=subprocess.PIPE, stderr=open(os.devnull, 'w'), shell=True)
    java_process.wait()
    assert not java_process.returncode, 'ERROR: Call to OLLIE exited with a non-zero code status.'

    #print(os.path.exists(newOutputName))
    #print(os.path.exists(tmp_output_folder))

    with open(newOutputName.strip(), 'r') as output_file:
        results_str = output_file.readlines()
    #os.remove(newOutputName.strip())
    #os.remove(new_filename)

    return __process(results_str)

#res=ollie_single("No, that is not the reason they exist. Every DM actually contains its DMKSP, DMSNES, and DMTS so at any point in time a DM can actually have only one DMXXX. We had arguments over sharing DM with multiple solvers but I think that is a goofy optimization.    Hmm, since PC/KSP/SNES/TS know about DM why don't we just stick that information in the solver. Seems simpler, there must be some reason.")
#print(res)
#object="(cat"
#print(object)
