/*
 * (c) 2015 - 2017 ENisco GmbH &amp; Co. KG
 */
package cas.ypsiliform.starter;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main
{

    private static String OS = System.getProperty("os.name").toLowerCase();

    //args:
    // 1. url to mediator-server 
    // 2. config file
    public static void main(String[] args)
        throws FileNotFoundException,
            IOException
    {
        if ( args.length != 2 )
        {
            throw new IllegalArgumentException("two arguments are required. 1. url, 2. config file");
        }

        String url = args[0];
        File config = new File(args[1]);

        Map<Integer, Double> storageCost = new HashMap<>();
        Map<Integer, Double> setupCost = new HashMap<>();
        Integer[] demands = new Integer[12];
        Map<Integer, List<Integer>> requires = new HashMap<>();
        Map<Integer, Integer> productionLimit = new HashMap<>();
        try (BufferedReader br = new BufferedReader(new FileReader(config)))
        {
            String line;
            boolean first = true;
            int lineCount = 0;

            while ( (line = br.readLine()) != null )
            {
                if ( first )
                {
                    first = false;
                    continue;
                }
                if ( line.trim().length() <= 0 )
                {
                    continue;
                }
                //split any whitespace
                String[] split = line.split("\\s+");
                if ( lineCount < 5 )
                {
                    storageCost.put(Integer.valueOf(split[0].trim()),
                                    Double.valueOf(split[1].trim()));
                }
                if ( lineCount >= 5 && lineCount < 10 )
                {
                    setupCost.put(Integer.valueOf(split[0].trim()),
                                  Double.valueOf(split[1].trim()));
                }
                if ( lineCount >= 10 && lineCount < 22 )
                {
                    demands[lineCount - 10] = Integer.valueOf(split[1].trim());
                }
                if ( lineCount >= 22 && lineCount < 27 )
                {
                    List<Integer> requiresTmp = readList(split);
                    requires.put(Integer.valueOf(split[0].trim()), requiresTmp);
                }
                if ( lineCount >= 27 && lineCount < 32 )
                {
                    productionLimit.put(Integer.valueOf(split[0].trim()),
                                        Integer.valueOf(split[1].trim()));
                }
                lineCount++;
            }
        }

        for ( int i = 1; i < 6; i++ )
        {
            Integer[] demandsTmp = new Integer[0];
            if ( i == 1 )
            {
                demandsTmp = demands;
            }
            String[] processArgs = getArgs(i,
                                           config.getName(),
                                           url,
                                           storageCost.get(i),
                                           setupCost.get(i),
                                           demandsTmp,
                                           requires.get(i),
                                           productionLimit.get(i));
            ProcessBuilder pb = new ProcessBuilder(processArgs);
            pb.start();
            System.out.println("Start agent " + i + " args "
                + Arrays.toString(processArgs));
        }
    }

    private static String[] getArgs(int id,
                                    String config,
                                    String url,
                                    double storageCost,
                                    double setupCost,
                                    Integer[] demands,
                                    List<Integer> requires,
                                    Integer productionLimit)
    {
        String[] args = new String[0];
        if ( isWindows() )
        {
            args =
                new String[] { "cmd", "/c", "start", "java", "-jar",
                    "agent.jar", String.valueOf(id), config, url,
                    String.valueOf(storageCost), String.valueOf(setupCost),
                    Arrays.toString(demands).replaceAll("\\s+", ""),
                    Arrays
                        .toString(requires
                            .toArray(new Integer[requires.size()]))
                        .replaceAll("\\s+", ""),
                    String.valueOf(productionLimit) };
        }
        else if ( isUnix() )
        {
            args =
                new String[] { "/usr/bin/bash", "-e", "java", "-jar",
                    "agent.jar", String.valueOf(id), config, url,
                    String.valueOf(storageCost), String.valueOf(setupCost),
                    Arrays.toString(demands).replaceAll("\\s+", ""),
                    Arrays
                        .toString(requires
                            .toArray(new Integer[requires.size()]))
                        .replaceAll("\\s+", ""),
                    String.valueOf(productionLimit) };
        }
        else if ( isMac() )
        {
            args = new String[] { "osascript", "-e",
                "tell application \"Terminal\" to do script \"java -jar agent.jar\"" };
        }
        return args;
    }

    private static List<Integer> readList(String[] split)
    {
        List<Integer> requires = new ArrayList<>();
        if ( split.length == 1 )
        {
            return requires;
        }
        for ( int i = 1; i < split.length; i++ )
        {
            requires.add(Integer.valueOf(split[i].trim()));
        }
        return requires;
    }

    public static boolean isWindows()
    {

        return (OS.indexOf("win") >= 0);

    }

    public static boolean isMac()
    {

        return (OS.indexOf("mac") >= 0);

    }

    public static boolean isUnix()
    {

        return (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0
            || OS.indexOf("aix") > 0);

    }

    public static boolean isSolaris()
    {

        return (OS.indexOf("sunos") >= 0);

    }

}

@@ -6207,31 +6207,25 @@
 urn 
-(
 OS.
-indexOf(%22win%22) %3E= 0
+contains(%22win%22
 );%0D%0A
@@ -6298,31 +6298,25 @@
 urn 
-(
 OS.
-indexOf(%22mac%22) %3E= 0
+contains(%22mac%22
 );%0D%0A
@@ -6390,96 +6390,70 @@
 urn 
-(
 OS.
-indexOf
+contains
 (%22nix%22)
- %3E= 0
  %7C%7C OS.
-indexOf(%22nux%22) %3E= 0%0D%0A            %7C%7C OS.indexOf
+contains(%22nux%22) %7C%7C OS.contains
 (%22aix%22)
- %3E 0)
 ;%0D%0A%0D
@@ -6529,19 +6529,19 @@
 urn 
-(
 OS.
-indexOf
+contains
 (%22su
@@ -6549,14 +6549,8 @@
 os%22)
- %3E= 0)
 ;%0D%0A%0D

change to contains