/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2005 C.Marchand - christophe.marchand@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package fr.gouv.finances.cp.xemelios.importers.transformers;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.zip.GZIPInputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import fr.gouv.finances.cp.utils.Base64;
import fr.gouv.finances.cp.utils.Pair;
import fr.gouv.finances.cp.xemelios.common.DematTransform;
import fr.gouv.finances.cp.xemelios.common.PJRef;
import fr.gouv.finances.cp.xemelios.data.DataLayerManager;
import fr.gouv.finances.cp.xemelios.utils.FileUtils;

public class PJTransformeur implements EtatTransformeur {

    private static Logger logger = Logger.getLogger(PJTransformeur.class);
    private int return_code;
    private String xsl_PJPESFACTURE_TO_XMLPESFACTURE = "PES_V2/PES-PJ_PESFACTURE.xsl";

    public void transform(Pair collectivite, String fileEncoding, String xmlVersion, String baseDirectory, String buff) {

        try {
            PJRef pjref = new PJRef();

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new ByteArrayInputStream(buff.getBytes(fileEncoding)));

            // la collectivité
            pjref.setCollectivite(collectivite.key);

            // PJ_NAME : IdUnique
            NodeList tmpNL = doc.getElementsByTagName("IdUnique");
            if (tmpNL.getLength() == 1) {
                Node n = tmpNL.item(0);
                pjref.setPjName(n.getAttributes().item(0).getNodeValue());
            }

            // FILe_NAME : NomPJ 
            tmpNL = doc.getElementsByTagName("NomPJ");
            if (tmpNL.getLength() == 1) {
                Node n = tmpNL.item(0);
                pjref.setFileName(n.getAttributes().item(0).getNodeValue());
            }
            byte[] data = null;
            // PES/Contenu/Fichier ou PES/Contenu/PES_Facture
            boolean isFICHIER = (doc.getElementsByTagName("Fichier").getLength() > 0);

            if (isFICHIER) {
                // lecture en base64 puis décompression GZip
                tmpNL = doc.getElementsByTagName("Fichier");
                if (tmpNL.getLength() == 1) {
                    Node n = tmpNL.item(0);
                    String encoded = n.getTextContent();

                    GZIPInputStream gzi = new GZIPInputStream(new ByteArrayInputStream(Base64.decode(encoded)));
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();

                    byte[] bTmp = new byte[2048];
                    int read = 0;
                    do {
                        read = gzi.read(bTmp);
                        if (read > 0) {
                            baos.write(bTmp, 0, read);
                        }
                    } while (read > 0);

                    baos.flush();
                    baos.close();
                    gzi.close();

                    data = baos.toByteArray();
                }
            } else {
                // application d'une xsl sur le PES_FACTURE pour en faire un doc XML valide
                File f = new File(new File(baseDirectory), xsl_PJPESFACTURE_TO_XMLPESFACTURE);
                String xsltBuffer = "";
                try {
                    String xslEncoding = FileUtils.getFileEncoding(f);
                    xsltBuffer = FileUtils.readTextFile(f, xslEncoding);
                } catch (IOException ioEx) {
                    logger.error("in TEtat.getImportXsltBuffer() :", ioEx);
                    return_code = RETURN_CODE_ERR;
                }
                HashMap<String, Object> parameters = new HashMap<String, Object>();
                InputStream is = DematTransform.transform(new ByteArrayInputStream(buff.getBytes(fileEncoding)),
                        new ByteArrayInputStream(xsltBuffer.replaceAll("##output-encoding##", fileEncoding).replaceAll("##xml-version##", xmlVersion).getBytes()), fileEncoding, parameters);

                StringBuffer newText = new StringBuffer();
                int len = 0;
                byte[] b = new byte[1024];
                do {
                    len = is.read(b);
                    if (len > 0) {
                        newText.append(new String(b, 0, len));
                    }
                } while (len > 0);

                data = newText.toString().getBytes();
            }
            pjref.setData(data);
            pjref.setUncompressedSize(data.length);

            DataLayerManager.getImplementation().importPj(pjref);
            return_code = RETURN_CODE_OK;
        } catch (Exception e) {
            logger.error("import PJ", e);
            return_code = RETURN_CODE_ERR;
        } catch (OutOfMemoryError oome) {
            logger.error("import PJ", oome);
            return_code = RETURN_CODE_ERR;
        }
    }

    public int getReturnCode() {
        return return_code;
    }
}
