package org.agmip.translators.csv;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import au.com.bytecode.opencsv.CSVReader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.agmip.core.types.TranslatorInput;

public class DomeInput implements TranslatorInput {
    private static final Logger log = LoggerFactory.getLogger(DomeInput.class);
    private HashMap<String, Object> dome = new HashMap<String, Object>();
    private ArrayList<String> generatorFunctions = new ArrayList<String>();


    public DomeInput() {
        generatorFunctions.add("AUTO_PDATE()");
    }

    public Map readFile(String fileName) throws Exception {
        if (fileName.toUpperCase().endsWith("CSV")) {
            FileInputStream stream = new FileInputStream(fileName);
            readCSV(new FileInputStream(fileName));
            stream.close();
        }
        return dome;
    }

    public void readCSV(InputStream stream) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(stream));
        HashMap<String, String> info  = new HashMap<String, String>();
        ArrayList<HashMap<String, String>> rules = new ArrayList<HashMap<String, String>>();
        CSVReader reader = new CSVReader(br);
        String[] nextLine;
        int ln = 0;
        boolean hasGenerator = false;

        while ((nextLine = reader.readNext()) != null) {
            HashMap<String, String> lineMap = new HashMap<String, String>();
            ln++;
            if (nextLine[0].startsWith("&")) {
                // This is an official dome line.
                log.debug("Found a DOME instruction at line {}", ln);
                String cmd = nextLine[1].trim().toUpperCase();
                if (cmd.equals("INFO")) {
                    info.put(nextLine[2].toLowerCase(), nextLine[3].toUpperCase());
                } else if ((cmd.equals("FILL") || cmd.equals("REPLACE"))) {
                    StringBuilder args = new StringBuilder();
                    if (nextLine[3].endsWith("()")) {
                        // Handle Arguments
                        if (generatorFunctions.contains(nextLine[3].toUpperCase())) {
                            hasGenerator = true;
                        }
                        int argLen = nextLine.length - 3;

                        if (argLen != 0) {
                            args.append(nextLine[3]);
                            if (argLen > 1) {
                                for( int i = 4; i < nextLine.length; i++) {
                                    args.append("|");  
                                    if (! nextLine[i].startsWith("!")) {
                                        args.append(nextLine[i].toUpperCase());
                                    }
                                }
                            }
                        }

                        log.debug("Current Args: {}", args.toString());
                        int chopIndex = args.indexOf("||", 0);
                        if (chopIndex == -1) {
                            chopIndex = args.length();
                        }
                        if (args.substring(0,chopIndex).endsWith("|")) {
                            chopIndex --;
                        }
                        lineMap.put("args", args.substring(0,chopIndex));
                    } else {
                        // Variable or static
                        lineMap.put("args", nextLine[3].toUpperCase());
                    }

                    lineMap.put("cmd", cmd);
                    lineMap.put("variable", nextLine[2]);
                    rules.add(lineMap);
                } else {
                    log.error("Found invalid command {} at line {}", cmd, ln);
                }
            } 
        }
        br.close();
        if (hasGenerator) {
            info.put("has_generator", "Y");
        }
        dome.put("info", info);
        dome.put("rules", rules);
    }

    public HashMap<String, Object> getDome() {
        return dome;
    }
}
@@ -1344,24 +1344,122 @@
 String%3E%3E();%0A
+        ArrayList%3CHashMap%3CString, String%3E%3E generators = new ArrayList%3CHashMap%3CString, String%3E%3E();%0A
         CSVR
@@ -1492,16 +1492,16 @@
 er(br);%0A
-
         
@@ -1631,24 +1631,65 @@
  != null) %7B%0A
+            boolean isGenerator = false;%0A
             
@@ -2315,24 +2315,102 @@
 th(%22()%22)) %7B%0A
+                        log.debug(%22Found fun %7B%7D%22, nextLine%5B3%5D.toUpperCase());%0A
             
@@ -2523,24 +2523,135 @@
 rCase())) %7B%0A
+                            log.debug(%22Found a generator!!!%22);%0A                            isGenerator = true;%0A
             
@@ -4076,24 +4076,145 @@
 xtLine%5B2%5D);%0A
+                    if (isGenerator) %7B%0A                        generators.add(lineMap);%0A                    %7D else %7B%0A    
             
@@ -4233,32 +4233,54 @@
 s.add(lineMap);%0A
+                    %7D%0A
                 
@@ -4449,32 +4449,47 @@
 (hasGenerator) %7B
+               
 %0A            inf
@@ -4489,22 +4489,18 @@
     
-info
+dome
 .put(%22
-has_
 gene
@@ -4508,14 +4508,22 @@
 ator
+s
 %22, 
-%22Y%22
+generators
 );%0A 

Enable generators for DOME