package org.texttechnologylab.project.gruppe_05_1;


import org.texttechnologylab.project.gruppe_05_1.database.*;
import org.texttechnologylab.project.gruppe_05_1.nlp.NlpUtils;
import org.texttechnologylab.project.gruppe_05_1.nlp.XmiExtractor;
import org.texttechnologylab.project.gruppe_05_1.rest.RESTHandler;
import org.texttechnologylab.project.gruppe_05_1.util.Logger;
import org.texttechnologylab.project.gruppe_05_1.util.PPRUtils;
import org.texttechnologylab.project.gruppe_05_1.xml.FileObjectFactory;
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.Interfaces.Session;
import org.texttechnologylab.project.gruppe_05_1.xml.speeches.SpeechParser;
import org.w3c.dom.Document;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static org.texttechnologylab.project.gruppe_05_1.util.PPRUtils.checkAndProcessNewProtocols;

public class Main {
    public static boolean UPLOAD_MEMBER_PHOTOS;
    public static boolean FORCE_UPLOAD_MEMBERS;
    public static boolean FORCE_UPLOAD_SPEECHES;
    public static boolean ONLY_RUN_WEB;
    public static boolean DEBUG_LOGGING;
    private static final FileObjectFactory xmlFactory = FileObjectFactory.getFactory();
    private static final MongoObjectFactory mongoFactory = MongoObjectFactory.getFactory();

    public static final String CONFIG_DIR = "src/main/resources/config";
    public static final String JAVALIN_TEMPLATE_DIR = "src/main/resources/templates";
    public static final String JAVALIN_STATIC_FILES_DIR = "src/main/resources/static";
    public static final String JCAS_SPEECHES_TYPESYSTEM_DIR = "src/main/resources/speeches/TypeSystem";
    public static final String MEMBER_IMAGES_DIR = "src/main/resources/membersOfParliamentImages/";

    public static void main(String[] args) throws Exception {
        UPLOAD_MEMBER_PHOTOS = Arrays.asList(args).contains("uploadMemberPhotos");
        FORCE_UPLOAD_MEMBERS = Arrays.asList(args).contains("forceUploadMembers");
        FORCE_UPLOAD_SPEECHES = Arrays.asList(args).contains("forceUploadSpeeches");
        ONLY_RUN_WEB = Arrays.asList(args).contains("onlyRunWeb");
        DEBUG_LOGGING = Arrays.asList(args).contains("debugLogging");

        System.out.println("Starting Multimodal Parliament Explorer...");
        System.out.println("--------------------------------------------o");
        System.out.println("Arguments:");
        System.out.println(" - Upload the Member Photos to the DB: " + UPLOAD_MEMBER_PHOTOS);
        System.out.println(" - Force Upload Members:               " + FORCE_UPLOAD_MEMBERS);
        System.out.println(" - Force Upload Speeches:              " + FORCE_UPLOAD_SPEECHES);
        System.out.println(" - Only Run javalin Web Server:        " + ONLY_RUN_WEB);
        System.out.println(" - Debug Logging:                      " + DEBUG_LOGGING);
        System.out.println("--------------------------------------------o");

        if (ONLY_RUN_WEB) {
            Logger.info("Starting Web Service...");
            RESTHandler restHandler = new RESTHandler();
            restHandler.startJavalin();
            return;
        }

        MongoDBHandler mongoDBHandler = new MongoDBHandler();

        SpeechIndexFactoryImpl speechIndexFactory = new SpeechIndexFactoryImpl();
        if ((mongoDBHandler.getDatabase().getCollection(MongoPprUtils.SPEECH_COLLECTION_NAME).countDocuments() != 0) && !FORCE_UPLOAD_SPEECHES) {
            Logger.info("Skipping Speech parsing and DB insertion as they are already present...");
        } else {
            Logger.warn("Deleting all speeches from DB if existing...");
            mongoDBHandler.deleteSpeechRelatedDocuments();

            Logger.pink("Parsing XML and inserting data into DB...");
            SpeechIndex speechIndex = speechIndexFactory
                    .parseLegislativePeriods(TRUE)
                    .builder()
                    .parseSessions()
                    .filterForCurrentMembers(FALSE)
                    .build();

            //speechIndex.printInfo();

            Logger.info("Data retrieved from DB:");
            Logger.info("SPEECHCOUNT: " + speechIndex.getSpeeches().size());
            Logger.info("SESSIONCOUNT: " + speechIndex.getSessions().size());
            Logger.info("AGENDAITEMCOUNT: " + speechIndex.getAgendaItems().size());

            mongoDBHandler.deleteSpeechRelatedDocuments(); // Clear speeches, sessions, agendas (history)

            Logger.pink("Adding Sessions to DB...");
            mongoDBHandler.insertSessions(speechIndex.getSessions());

            Logger.pink("Adding Agenda Items to DB...");
            mongoDBHandler.insertAgendaItems(speechIndex.getAgendaItems());

            Logger.pink("Adding Speeches to DB...");
            mongoDBHandler.insertSpeeches(speechIndex.getSpeeches());

            // only upload member photos if database was empty by default, not when speeches are force-overwritten
            if (!FORCE_UPLOAD_SPEECHES) {
                Logger.pink("Uploading Member Photos to DB...");
                mongoDBHandler.uploadMemberPhotos();
            }
        }

        // Alle Informationen (Parlamentarier, Reden, Kommentare etc.) lesen und in die Mongo-DB einfügen, falls diese noch nicht vorhanden sind.
        PPRUtils.parlamentExplorerInit(xmlFactory, mongoFactory);

        //das muss auf jeden fall noch angepasst werden xd
        if(mongoDBHandler.checkAnalysisResultsField() < 21518) {
            try {
                long startTime = System.currentTimeMillis();

                XmiExtractor extractor = new XmiExtractor();
                extractor.extractAndUploadXmiData();

                long endTime = System.currentTimeMillis();
                Logger.pink("Execution time: " + (endTime - startTime) + " ms");
            } catch (Exception e) {
                Logger.error(e.getMessage());
            }
        }

        if (UPLOAD_MEMBER_PHOTOS) {
            Logger.pink("Uploading Member Photos to DB...");
            mongoDBHandler.uploadMemberPhotos();
        }
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        scheduler.scheduleAtFixedRate(() -> {
            try {
                NlpUtils.runRemoteDriver();
            } catch (Exception e) {
                Logger.error("Error while running NLP remote driver");
                Logger.error(e.getMessage());
            }
            try {
                Logger.info("Starte Aktualisierung der Protokolle...");
                Set<Document> newProtocols = checkAndProcessNewProtocols(mongoDBHandler);
                Logger.info("Neue Protokolle gefunden: " + newProtocols.size());
                if (newProtocols.isEmpty()) {
                    Logger.info("Keine neuen Protokolle gefunden, Upload wird übersprungen.");
                } else {
                    SpeechParser speechParser = new SpeechParser();
                    List<Session> newSessions = speechParser.parseAllSessions(newProtocols);
                    mongoDBHandler.insertSessions(newSessions);
                    mongoDBHandler.insertAgendaItems(speechParser.getAgendaItems());
                    mongoDBHandler.insertSpeeches(speechParser.getSpeeches());
                    Logger.info("Neuer Protokolle uploaded: " + newProtocols.size());
                }
            } catch (Exception ex) {
                Logger.error("Fehler bei der Protokollaktualisierung: " + ex.getMessage());
            }
        }, 0, 10, TimeUnit.MINUTES);

        RESTHandler restHandler = new RESTHandler();
        restHandler.startJavalin();

    }
}

