/*
 * MUZG.java
 *
 * Autor: Piotr Achinger <piotr.achinger at gmail.com>
 */
package dendrarium.muzg;

import dendrarium.core.entities.Answer;
import dendrarium.trees.AnswerType;
import dendrarium.core.entities.TaskBusinessProcess;
import dendrarium.core.entities.TaskBusinessProcessState;
import dendrarium.trees.disamb.Disambiguator;
import dendrarium.trees.disamb.MUZGDisambiguator;
import dendrarium.trees.disamb.QuietDisambiguator;
import dendrarium.trees.xml.ForestExportFormat;
import dendrarium.trees.xml.TreeXMLExporter;
import dendrarium.trees.xml.TreeXMLParser;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.hibernate.Session;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

/**
 *
 * @author ks
 */
@Name("muzg")
@Scope(ScopeType.EVENT)
public class MUZG {

    public 
    @In
    Session session;

    private void copyOldAnswer(Answer oldAnswer, Answer newAnswer) {
        newAnswer.setType(oldAnswer.getType());
        newAnswer.setAnswer(oldAnswer.getAnswer());
        newAnswer.setComment(oldAnswer.getComment());
        newAnswer.setSelectDate(oldAnswer.getSelectDate());
        newAnswer.setAccepted(oldAnswer.isAccepted());
        newAnswer.setRefreshedByMUZG(oldAnswer.isRefreshedByMUZG());
    }

    /** Próbujemy przepisać starą odpowiedź na nową - szczegóły w komentarzu do
     * chooseAuto w MUZGDisambiguatorze.
     */
    public Answer adapt(Answer oldAnswer, TaskBusinessProcess newTask) {
        try {
            if (oldAnswer == null) {
                return null;
            }
            Answer newAnswer = new Answer(oldAnswer.getUser(), newTask);
            if (AnswerType.SENTENCE_ERRORS.contains(oldAnswer.getType()) ||
                    oldAnswer.getType() == AnswerType.MORPH) {
                copyOldAnswer(oldAnswer, newAnswer);
                return newAnswer;
            } 

            newAnswer.setType(AnswerType.FULL);
            
            Disambiguator newAnswerDisambiguator = new QuietDisambiguator(new TreeXMLParser().parse(newTask.getTask().getForestXML()));
            Disambiguator oldAnswerDisambiguator = new MUZGDisambiguator(new TreeXMLParser().parse(oldAnswer.getAnswer()), newAnswerDisambiguator);

            oldAnswerDisambiguator.saturate();
            newAnswerDisambiguator.saturate();

            if (oldAnswer.getType() == AnswerType.NO_TREE) {
                newAnswer.setType(AnswerType.NO_TREE);
                newAnswer.setAnswer(newTask.getTask().getForestXML());
                if (newAnswerDisambiguator.noTrees()) {
                    copyOldAnswer(oldAnswer, newAnswer);
                } else {
                    makeRefreshedAnswer(newAnswer, oldAnswer);
                    makeRefreshedAnswer(newAnswer, oldAnswer);
                }
            } else {
                // FULL
                newAnswer.setAnswer(new TreeXMLExporter().export(newAnswerDisambiguator.getForest(), ForestExportFormat.NO_METADATA));
                if (newAnswerDisambiguator.isDone()) {
                    copyOldAnswer(oldAnswer, newAnswer);
                } else {
                    makeRefreshedAnswer(newAnswer, oldAnswer);
                }
            }

            return newAnswer;
        } catch (Exception ex) {
            Logger.getLogger(MUZG.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    private void makeRefreshedAnswer(Answer newAnswer, Answer oldAnswer) {
        newAnswer.setAccepted(false);
        newAnswer.setRefreshedByMUZG(true);
        if (oldAnswer.isAccepted()) {
            String comment = "Typ Twojej odpowiedzi odrzuconej "
                    + "przez nową gramatykę: " + oldAnswer.getType().getName();
            if (!oldAnswer.getComment().isEmpty()) {
                comment += " Twój poprzedni komentarz: "
                        + oldAnswer.getComment();
            }
            newAnswer.setComment(comment);
        } else {
            newAnswer.setComment("Zdanie zostało cofnięte, ale i tak nie miałeś/aś zaakceptowanej odpowiedzi.");
        }
    }

    public String adapt(TaskBusinessProcess oldTask, TaskBusinessProcess newTask) {
        String message = "";
        Answer new1 = adapt(oldTask.getUser1Answer(), newTask);
        Answer new2 = adapt(oldTask.getUser2Answer(), newTask);
        if (new1 != null)
            session.persist(new1);
        newTask.setUser1Answer(new1);
        if (new2 != null)
            session.persist(new2);
        newTask.setUser2Answer(new2);
        //newTask.setSuperAnswer(adapt(oldTask.getSuperAnswer(), newTask));

        Answer oldSuperAns = oldTask.getSuperAnswer();
        if (oldSuperAns != null) {
            if (oldSuperAns.getUser() == null) { // autoodpowiedź przy zgodności
                Answer newSuperAns = adapt(oldSuperAns, newTask);
                if (!newSuperAns.isAccepted()) {
                    String comment = "Była zgodność, ale nie pasowała do nowej "
                            + "gramatyki. Typ poprzedniej odpowiedzi: "
                            + oldSuperAns.getType().getName();
                    String comment1 = "", comment2 = "";
                    if (!oldTask.getUser1Answer().getComment().isEmpty()) {
                        comment1 = " Twój poprzedni komentarz: "
                                + oldTask.getUser1Answer().getComment();
                    }
                    if (!oldTask.getUser2Answer().getComment().isEmpty()) {
                        comment2 = " Twój poprzedni komentarz: "
                                + oldTask.getUser2Answer().getComment();
                    }
                    new1.setComment(comment + comment1);
                    new1.setComment(comment + comment2);
                } else { // przechodzi jako autoodpowiedź
                    session.persist(newSuperAns);
                    newTask.setSuperAnswer(newSuperAns);
                }
            } else {
                Answer newSuperAns = adapt(oldSuperAns, newTask);
                if (newSuperAns.isAccepted()) { // superodpowiedź przeszła, czyli dendrologów sztucznie akceptujemy
                    if (!new1.isAccepted()) {
                        new1.setType(AnswerType.NO_TREE);
                        new1.setAccepted(true);
                        new1.setRefreshedByMUZG(false);
                    }
                    if (!new2.isAccepted()) {
                        new2.setType(AnswerType.NO_TREE);
                        new2.setAccepted(true);
                        new2.setRefreshedByMUZG(false);
                    }
                    session.persist(newSuperAns);
                    newTask.setSuperAnswer(newSuperAns);
                } else {
                    String comment1 = " Typ Twojej odpowiedzi: "
                            + oldTask.getUser1Answer().getType().getName();
                    String comment2 = " Typ Twojej odpowiedzi: "
                            + oldTask.getUser2Answer().getType().getName();
                    if (!oldTask.getUser1Answer().getComment().isEmpty()) {
                        comment1 += " Twój poprzedni komentarz: "
                            + oldTask.getUser1Answer().getComment();
                    }
                    if (!oldTask.getUser2Answer().getComment().isEmpty()) {
                        comment2 += " Twój poprzedni komentarz: "
                            + oldTask.getUser2Answer().getComment();
                    }
                    if (oldSuperAns.getType() == AnswerType.FULL) {
                        String comment = "Zadanie automatycznie cofnięte. "
                                + "Superdendrolog dał odpowiedź pełną, "
                                + "ale niezgodną z nową gramatyką. "
                                + "Typ odpowiedzi superdendrologa: "
                                + oldSuperAns.getType().getName();
                        if (!oldSuperAns.getComment().isEmpty()) {
                            comment += " Komentarz superdendrologa: "
                                    + oldSuperAns.getComment();
                        }
                        new1.setAnswer(newSuperAns.getAnswer());
                        new1.setType(AnswerType.FULL);
                        new1.setComment(comment + comment1);
                        new1.setRefreshedByMUZG(true);
                        new1.setAccepted(false);
                        new2.setAnswer(newSuperAns.getAnswer());
                        new2.setType(AnswerType.FULL);
                        new2.setComment(comment + comment2);
                        new2.setRefreshedByMUZG(true);
                        new2.setAccepted(false);
                    } else { // odrzucone NO_TREE supera
                        String comment = "W poprzedniej wersji gramatyki superdendrolog powiedział, że nie ma poprawnego drzewa.";
                        if (!oldSuperAns.getComment().isEmpty()) { // czyli zawsze?
                            comment += " Komentarz superdendrologa: "
                                    + oldSuperAns.getComment();
                        }
                        new1.setAnswer(newTask.getTask().getForestXML());
                        new1.setType(AnswerType.NO_TREE);
                        new1.setComment(comment + comment1);
                        new1.setRefreshedByMUZG(true);
                        new1.setAccepted(false);
                        new2.setAnswer(newTask.getTask().getForestXML());
                        new2.setType(AnswerType.NO_TREE);
                        new2.setComment(comment + comment2);
                        new2.setRefreshedByMUZG(true);
                        new2.setAccepted(false);
                    }
                }
            }
        }

        newTask.updateState();
        return message;
    }
}
