/*
 * Copyright
 *   2005 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 General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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.dgfip.xemelios.common.config;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.xml.sax.SAXException;

/**
 * Provides helper method to load config files
 * @author chm
 */
public class Loader {
    private static final Logger logger = Logger.getLogger(Loader.class);
    private static DocumentsModel cache = null;
    
    /**
     * Loads and returns config files. If config files contains at least one error, returns an empty DocumentsModel.
     * @param repertoires A comma-separated list of directories where to find config files
     * @return DocumentsModel the fully-assembled config
     */
    protected static DocumentsModel getDocsInfos(String repertoires) throws SAXException, ParserConfigurationException, IOException {
        DocumentsModel ret = cache;
        if(ret==null) {
            String[] dirs = repertoires.split(",");
            for(String repertoire:dirs) {
                File dir = new File(repertoire);
                logger.info("Searching " + repertoire);
                if (!dir.exists()) {
                    logger.info(repertoire + " does not exists.");
                    continue;
                }
                // Fichiers de config
//                logger.debug("listing files");
                File[] fichiers = dir.listFiles(new FilenameFilter() {
                    public boolean accept(File dir, String name) {
                        boolean ret = name.toUpperCase().endsWith(".XML") && !"build.xml".equals(name);
//                        logger.debug(name+"->"+Boolean.toString(ret));
                        return ret;
                    }
                });
                if (fichiers == null) {
                    logger.info("No file found in " + repertoire);
                    return null;
                }
                DocumentsParser dp = new DocumentsParser();
                for (int i = 0; i < fichiers.length; i++) {
//                    logger.debug("parsing "+fichiers[i].getAbsolutePath());
                    try {
                        dp.parse(fichiers[i]);
                    } catch(Exception ex) {
                        logger.error("while parsing "+fichiers[i].getAbsolutePath(),ex);
                    }
                    DocumentsModel dm = (DocumentsModel) dp.getMarshallable();
                    if (ret == null) {
                        ret = dm;
                        for(DocumentModel docModel:ret.getDocuments()) {
//                            logger.debug("adding "+docModel.getId());
                            docModel.setBaseDirectory(repertoire);
                        }
                    } else {
                        for(DocumentModel docModel : dm.getDocuments()) {
                            docModel.setBaseDirectory(repertoire);
//                            logger.debug("adding "+docModel.getId());
                            ret.addChild(docModel, DocumentModel.QN);
                        }
                    }
                }
            }
            for(String repertoire:dirs) {
                // fichiers d�riv�s d'une config
                File dir = new File(repertoire);
                logger.info("Searching " + repertoire);
                if (!dir.exists()) {
                    logger.info(repertoire + " does not exists.");
                    continue;
                }
                File[] fichiers = dir.listFiles(new FilenameFilter() {
                    public boolean accept(File dir, String name) {
                        return name.toUpperCase().endsWith(".EXML");
                    }
                });
                if (fichiers == null) {
                    logger.info("No file found in " + repertoire);
                    return null;
                }
                for(File f:fichiers) {
                    DocumentsParser dp = new DocumentsParser();
                    dp.setInitialData(ret);
                    dp.parse(f);
                    ret = (DocumentsModel)dp.getMarshallable();
                    for(DocumentModel docModel:ret.getDocuments()) {
                        if(docModel.getBaseDirectory()==null)
                            docModel.setBaseDirectory(repertoire);
                    }
                }
            }
            cache = ret;
        }
//        logger.debug("cache contains "+cache.getDocuments().size()+" doc models");
        return ret;
    }
    
    public static DocumentsModel getDocumentsInfos(String repertoires) throws SAXException, ParserConfigurationException, IOException {
        DocumentsModel ret = getDocsInfos(repertoires);
        try {
            ret.validate();
        } catch(Throwable t) {
            logger.error("while loading config files: "+t);
            t.printStackTrace();
            ret = new DocumentsModel(DocumentsModel.QN);
        }
//        logger.debug("exiting successfully getDocumentsInfos");
//        for(DocumentModel dm:ret.getDocuments()) {
//            logger.debug(dm.getId()+" -> "+dm.getTitre());
//        }
        return ret;
    }
    public static void flushLoadedConfig() {
        cache=null;
    }
    
}
