/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *  2009 Laurent Meckert <laurent.meckert@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.controls.editors;

import java.util.Hashtable;
import java.math.BigDecimal;
import java.io.FileOutputStream;

import java.util.Properties;
import java.io.FileInputStream;





import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;



import java.io.File;

/**
 *
 * @author laurent.meckert
 */
public class CommandLineController {

   static Controller controller;

   protected static Object controlParameterFromString(String paramId, String paramValue) {
      // in control config file, param types are
      //  string  -> java.lang.String
      //  boolean -> java.lang.Boolean
      //  decimal -> java.math.BigDecimal
      //  integer -> java.lang.Integer
      //
      // multi-valued params are String arrays (java.lang.String[]) values


      String dataType = controller.getParameterDataType(paramId);
      if (dataType == null) {
         System.err.println("Unknown parameter :" + paramId);
         return null;
      }
      if ("string".equals(dataType)) {
         if (paramValue.matches("\\{.*\\}")) {

            int i1 = paramValue.indexOf("{");
            int i2 = paramValue.lastIndexOf("}");
            paramValue = paramValue.substring(i1 + 1, i2);
            System.err.println("Splitting :" + paramValue);
            return paramValue.split(" *, *");
         } else {
            return paramValue;
         }
      } else if ("boolean".equals(dataType)) {
         return new Boolean(paramValue);
      } else if ("decimal".equals(dataType)) {
         return new BigDecimal(Long.parseLong(paramValue));
      } else if ("integer".equals(dataType)) {
         return new Integer(Integer.parseInt(paramValue));
      } else {
         System.err.println("Unknown data type :" + dataType);
         return null;
      }
      // here, filled with default values from PES as an example
//      if ("nomencl".equals(paramId) || "typnomencl".equals(paramId)) {
//         return paramValue;
//      }
//      //ret.put("nomencl", "M14");   // values can be M14, M21, M22, M31, M52, M61, M71
//
//      // ret.put("typnomencl", "Nature"); // values can be Nature, Fonction, Nature-ref-fonct
//      if ("votop".equals(paramId) || "suivdgp".equals(paramId) || "coltva".equals(paramId)) {
//         return new Boolean(paramValue);
//      }
//
//      //  ret.put("votop", Boolean.FALSE);
//      //  ret.put("suivdgp", Boolean.TRUE);
//      //  ret.put("coltva", Boolean.TRUE);
//      if ("seuilMax".equals(paramId) || "seuilEmission".equals(paramId)) {
//         return new BigDecimal(Long.parseLong(paramValue));
//      }
//
//      //ret.put("seuilMax", new BigDecimal(90000));
//      //         ret.put("seuilEmission", new BigDecimal(10));
//      if ("dureedgp".equals(paramId)) {
//         return new Integer(Integer.parseInt(paramValue));
//      }
//      //ret.put("dureedgp", new Integer(45));
//      if ("servTVA".equals(paramId) || "compteTVA".equals(paramId) || "tauxTVA".equals(paramId) || "codProd".equals(paramId)) {
//         return paramValue.split(" *, *");
//
//      }
      //         ret.put("servTVA", new String[]{}); // list of services
      //         ret.put("compteTVA", new String[]{}); // list of comptes
      //         ret.put("tauxTVA", new String[]{"2.1", "5.5", "19.6"}); // String array of VAT rates
      //
      //         ret.put("codProd", new String[]{"69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80",
      //                    "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97",
      //                    "98", "99", "100", "101", "102", "103", "104", "105", "106", "107", "248", "300", "302", "305",
      //                    "306", "307", "308"}); // String array of product codes


   }

   protected static Hashtable<String, Object> getControlParameters(String propertiesFile) throws Exception {
      // Read properties file.
      Properties properties = new Properties();

      properties.load(new FileInputStream(propertiesFile));
      Hashtable<String, Object> ret = new Hashtable<String, Object>();
      for (Object obk : properties.keySet()) {
         String sk = obk.toString();

         ret.put(sk, controlParameterFromString(sk, properties.getProperty(sk)));
      }
      return ret;
   }

   /**
    * Appel en ligne de commande
    * @param args = type de document, fichier à analyser, répertoire de génération, fichier de properties
    */
   public static void main(String[] args) {
      try {

         // si pas assez d'arguments = on donne le modele d'appel et on sort
         if (args.length < 4) {

            System.err.println("Usage : CommandLineController DocType FileToParse GenerationDirectory PropertiesFile");
            System.exit(1);
         }


         String typeDoc = args[0];
         String fileToReadPath = args[1];
         String dirToGeneratePath = args[2];
         String propertiesFilePath = args[3];

         File fileToRead = new File(fileToReadPath);


         controller = new Controller(typeDoc);
         Hashtable<String, Document> result = controller.controle(fileToRead, getControlParameters(propertiesFilePath));

         // si on est ici = on peut au moins generer le rapport
         // donc on tente de creer le repertoire de sortie
         File dirToGenerate = new File(dirToGeneratePath);
         if (dirToGenerate.exists()) {
            if (!dirToGenerate.isDirectory()) {
               throw new Exception(dirToGeneratePath + " exists and is not a directory");
            }
         } else {
            dirToGenerate.mkdirs();
         }

         for (String k : result.keySet()) {
            Document doc = result.get(k);

            try {
               File fn = new File(dirToGenerate,
                       k + ".xml");
               FileOutputStream f = new FileOutputStream(fn);

               TransformerFactory tf = TransformerFactory.newInstance();
               Transformer t = tf.newTransformer();
               t.setOutputProperty("encoding", "ISO-8859-1");
               t.setOutputProperty("method", "xml");
               t.setOutputProperty("indent", "yes");
               t.transform(new DOMSource(doc), new StreamResult(f));

               f.flush();
               f.close();
               System.out.println("Generated " + fn.getAbsolutePath() + ".");

            } catch (Exception e) {
               e.printStackTrace();
               //

            } catch (Error e) {
               e.printStackTrace();


            }
         }

      } catch (Throwable t) {
         t.printStackTrace();
      }
   }
}
