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

import dendrarium.core.entities.Answer;
import dendrarium.core.entities.User;
import dendrarium.trees.AnswerData;
import dendrarium.trees.Forest;
import dendrarium.trees.xml.ForestExportFormat;
import dendrarium.trees.xml.TreeXMLExporter;
import dendrarium.trees.xml.TreeXMLParser;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import javax.faces.context.FacesContext;
import org.hibernate.Session;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.core.Manager;
import org.jboss.seam.document.DocumentData;
import org.jboss.seam.document.DocumentStore;
import org.jboss.seam.faces.RedirectException;
import org.jboss.seam.log.Log;

/**
 *
 * @author Piotr Achinger <piotr.achinger at gmail.com>
 */
@Name("download")
@Scope(ScopeType.SESSION)
public class Download implements Serializable {

    @In
    FacesContext facesContext;

    @RequestParameter
    Long answerId;

    @In
    Session session;

    @In
    User user;

    @In
    Manager manager;

    @Logger
    Log log;

    private ForestExportFormat exportFormat;

    public ForestExportFormat[] getAvailableExportFormats() {
        return ForestExportFormat.values();
    }

    public ForestExportFormat getExportFormat() {
        if (exportFormat == null) {
            this.exportFormat = ForestExportFormat.ONLY_CHOSEN;
        }
        return exportFormat;
    }

    public void setExportFormat(ForestExportFormat exportFormat) {
        this.exportFormat = exportFormat;
    }

    public void download() {
        user = (User) session.merge(user);

        Answer answer = (Answer) session.get(Answer.class, answerId);

        byte[] data = writeAnswer(answer, exportFormat);

        DocumentStore documentStore = DocumentStore.instance();

        DocumentData dd = new DocumentData("forest", new DocumentData.DocumentType("xml", "application/xml"), data);

        dd.setDisposition("attachment");

        String id = documentStore.newId();

        documentStore.saveData(id, dd);

        String documentUrl =
               documentStore.preferredUrlForContent(
                dd.getBaseName(),
                dd.getDocumentType().getExtension(),
                id);
        System.out.println("XML DOCUMENT " + documentUrl);

        redirect(documentUrl);
    }

    protected void redirect(String url) {
        try {
            facesContext.getExternalContext().redirect(manager.encodeConversationId(url, manager.getCurrentConversationViewId()));
        } catch (IOException ioe) {
            throw new RedirectException(ioe);
        }
    }

    public byte[] writeAnswer(Answer answer, ForestExportFormat format) {
        byte[] data;
        try {
            data = answer.getAnswer().getBytes("UTF-8");
        } catch (UnsupportedEncodingException ex) {
            if (log != null) {
                log.error(ex);
            } else {
                System.err.println(ex);
            }
            return new byte[0];
        }

        if (log != null) {
            log.info("EXPORT -> " + format);
        }

        if (format == ForestExportFormat.NO_METADATA) {
            return data;
        }

        Forest forest;
        try {
            forest = new TreeXMLParser().parse(new ByteArrayInputStream(data));
        } catch (Exception ex) {
            log.error(ex);
            return new byte[0];
        }

        forest.setAnswerData(new AnswerData(answer));
        if (answer == answer.getTaskBusinessProcess().getSuperAnswer()) {
            forest.setExtraAnswerData1(new AnswerData(answer.getTaskBusinessProcess().getUser1Answer()));
            forest.setExtraAnswerData2(new AnswerData(answer.getTaskBusinessProcess().getUser2Answer()));
        }

        String output = new TreeXMLExporter().export(forest, format);

        byte[] ret;
        try {
            ret = output.getBytes("UTF-8");
        } catch (UnsupportedEncodingException ex) {
            log.error(ex);
            return new byte[0];
        }

        return ret;
    }
}
