import db, benchmark, gpt, report, os, time
from datetime import datetime
from report import build_pptx, save_chart_png, render_html_table
import sys
import atexit

def is_already_running():
    """Controlla se un'altra istanza dello script è già in esecuzione"""
    lock_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), "tmp/main.lock")
    
    # Se il file di lock esiste, controlla se il processo è ancora attivo
    if os.path.exists(lock_file):
        try:
            # Prova ad aprire il file per verificare se è bloccato
            with open(lock_file, 'w') as f:
                # Se riusciamo a scrivere, significa che il precedente processo è terminato male
                # senza rimuovere il file di lock
                pass
            # Rimuovi il vecchio file di lock
            os.unlink(lock_file)
        except IOError:
            # Il file è bloccato, significa che un'altra istanza è in esecuzione
            print("Un'altra istanza dello script è già in esecuzione. Uscita.")
            return True
    
    # Crea un nuovo file di lock
    try:
        with open(lock_file, 'w') as f:
            f.write(str(os.getpid()))
        # Registra una funzione per rimuovere il file al termine
        atexit.register(lambda: os.path.exists(lock_file) and os.unlink(lock_file))
        return False
    except:
        print("Impossibile creare il file di lock")
        return True

def loop():
    #while True:
    if True: # for testing, run only once
        with db.conn() as connection:
            cursor = connection.cursor()
            #cursor.execute("SELECT id, answer_id FROM processing_queue WHERE status='NEW' LIMIT 1 FOR UPDATE SKIP LOCKED")
            cursor.execute("SELECT id, id_survey_item as answer_id FROM processing_queue WHERE status='NEW' LIMIT 1 FOR UPDATE")
            row = cursor.fetchone()
            if not row:
                time.sleep(5)
                #continue
                return
            job_id, ans_id = row
            cursor.execute("UPDATE processing_queue SET status='RUNNING', started_at=%s WHERE id=%s",
                      (datetime.utcnow(), job_id))
            connection.commit()

        try:
            print("Processing job", job_id, "for answer_id", ans_id)
            print("Benchmarking answer_id", ans_id)
            table = benchmark.compute(ans_id)
            #print(table)
            if not table:
                raise ValueError("No data found for answer_id {}".format(ans_id))
            print("Benchmarking done, generating narrative and PPTX")
            text, sim_ids = gpt.narrative(table)
            print("Narrative generated, sim_ids:", sim_ids)
            #print(text)
            if not text:
                raise ValueError("No narrative generated for answer_id {}".format(ans_id))
            png = report.make_charts(table)
            print("Charts created, building PPTX")
            #pptx_url = os.getenv("PPTX_URL", "http://localhost:8000/reports/")
            #pptx = report.build_pptx(ans_id, text, png)
            chart_path = report.save_chart_png(table, ans_id)
            pptx = "" #report.build_pptx(ans_id, text, chart_path)
            html_table = report.render_html_table(table)
            html_narrative = text.replace("\n", "<br>")
            print("Graph built, saving results to database")

            db.insert_result(ans_id, table, text, pptx_url=pptx, chart_url=chart_path, html_table=html_table, html_narrative=html_narrative)

            with db.conn() as connection:
                cursor = connection.cursor()
                cursor.execute("UPDATE processing_queue SET status='DONE', ended_at=%s WHERE id=%s",
                          (datetime.utcnow(), job_id))
                connection.commit()
        except Exception as e:
            with db.conn() as connection:
                cursor = connection.cursor()
                cursor.execute("UPDATE processing_queue SET status='ERROR', error_msg=%s WHERE id=%s",
                          (str(e), job_id))
                connection.commit()
            print("ERROR job", job_id, e)

def main():
    print("Script avviato")
    # Simulazione di esecuzione
    for i in range(10):
        print(f"Esecuzione in corso... {i+1}/10")
        time.sleep(1)
    print("Script completato")

if __name__ == "__main__":
    if is_already_running():
        sys.exit(1)
    loop()
