package org.agmip.translators.apsim;

import static org.agmip.util.JSONAdapter.toJSON;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Map;

import org.agmip.core.types.TranslatorOutput;
import org.agmip.translators.apsim.core.ACE;
import org.agmip.translators.apsim.core.Weather;
import org.agmip.translators.apsim.util.Util;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.codehaus.jackson.map.ObjectMapper;

/**
 * @author Ioannis N. Athanasiadis, DUTh
 * @author Dean Holzworth, CSIRO
 * @author Chris Villalobos, AgMIP IT
 * @since Jul 13, 2012
 */

public class ApsimWriter implements TranslatorOutput {
	static final int BUFFER = 2048;

	
	// Convert a JSON string into a collection of simulations
    public static ACE jsonToACE(String json) throws Exception{       
		ObjectMapper mapper = new ObjectMapper();
        ACE ace = mapper.readValue(json, ACE.class);
        ace.initialise();
        return ace;
    }	
	
	
	@SuppressWarnings({ "rawtypes" })
    @Override
	public void writeFile(String filePath, Map input) {

		try {
			ACE ace = jsonToACE(toJSON(input));
			File path = new File(filePath);

            // Check to see which files should be generated.
			ArrayList<String> files = new ArrayList<String>();
            if (! ace.getWeathers().isEmpty())
                generateMetFiles(path, ace, files);
           
            if (ace.getSoils().size() > 0 || ace.getExperiments().size() > 0)
                generateAPSIMFile("AgMip.apsim", path, ace, files);
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

    public static void generateMetFiles(File path, ACE ace, ArrayList<String> files) throws Exception {
        path.mkdirs();
        for(Weather weather:ace.getWeathers()){
            String fileName = weather.getName()+".met";
            File file = new File(path, fileName);
            files.add(fileName);
            file.createNewFile();
            Velocity.init();
            VelocityContext context = new VelocityContext();
            context.put("weather", weather);
            FileWriter writer = new FileWriter(file);
            Reader R = new InputStreamReader(Util.class.getClassLoader().getResourceAsStream("template.met"));
            Velocity.evaluate(context, writer, "Generate Met", R);
            writer.close();
        }
    }


    public static void generateAPSIMFile(String fileNameToGenerate, File path, ACE ace, ArrayList<String> files)
            throws Exception {
        path.mkdirs();
        File file = new File(path, fileNameToGenerate);
        files.add(fileNameToGenerate);
        file.createNewFile();
        Velocity.init();
        VelocityContext context = new VelocityContext();
        FileWriter writer;
        try {
            context.put("collection", ace);
            writer = new FileWriter(file);
            Reader R = new InputStreamReader(Util.class.getClassLoader().getResourceAsStream("template.apsim"));
            Velocity.evaluate(context, writer, "Generate APSIM", R);
            writer.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

@@ -242,16 +242,39 @@
 ayList;%0A
+import java.util.List;%0A
 import j
@@ -379,16 +379,68 @@
 re.ACE;%0A
+import org.agmip.translators.apsim.core.Simulation;%0A
 import o
@@ -1172,21 +1172,21 @@
 %0A    %7D%09%0A
-%09%0A%09%0A%09
+%0A    
 @Suppres
@@ -1196,17 +1196,16 @@
 rnings(%7B
- 
 %22rawtype
@@ -1206,17 +1206,16 @@
 awtypes%22
- 
 %7D)%0A    @
@@ -1223,17 +1223,20 @@
 verride%0A
-%09
+    
 public v
@@ -1284,19 +1284,34 @@
  %7B%0A%0A
-%09%09try %7B%0A%09%09%09
+        try %7B%0A            
 ACE 
@@ -1342,19 +1342,28 @@
 nput));%0A
-%09%09%09
+            
 File pat
@@ -1448,19 +1448,28 @@
 erated.%0A
-%09%09%09
+            
 ArrayLis
@@ -1528,17 +1528,16 @@
    if (!
- 
 ace.getW
@@ -1556,16 +1556,18 @@
 Empty())
+ %7B
 %0A       
@@ -1622,16 +1622,19 @@
         
+ %7D%0A
 %0A       
@@ -1703,16 +1703,18 @@
 e() %3E 0)
+ %7B
 %0A       
@@ -1726,66 +1726,679 @@
     
-generateAPSIMFile(%22AgMip.apsim%22, path, ace, files);%0A%09%09%09%0A%09%09
+int maxRun = 1500;%0A                if (ace.getExperiments().size() %3C= maxRun) %7B%0A                    generateAPSIMFile(%22AgMip.apsim%22, path, ace, files);%0A                %7D else %7B%0A                    List%3CSimulation%3E exps = new ArrayList%3CSimulation%3E();%0A                    exps.addAll(ace.getExperiments());%0A                    %0A                    for (int i = 0; i * maxRun %3C exps.size(); i++) %7B%0A                        ace.setExperiments(exps.subList(i * maxRun, Math.min((i + 1) * maxRun, exps.size())));%0A                        generateAPSIMFile(String.format(%22AgMip%2502d.apsim%22, i + 1), path, ace, files);%0A                    %7D%0A                %7D%0A            %7D%0A%0A        
 %7D ca
@@ -2421,11 +2421,20 @@
 ) %7B%0A
-%09%09%09
+            
 e.pr
@@ -2454,14 +2454,23 @@
 ();%0A
-%09%09%7D%0A%0A%09
+        %7D%0A%0A    
 %7D%0A%0A 

Add new feature that splitting the large data set into multiple smaller pieces. Current max run number per piece is 1500.