package innovimax.mixthem.arguments;

import innovimax.mixthem.exceptions.ArgumentException;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* <p>Mix-them command line arguments management.</p>
* @author Innovimax
* @version 1.0
*/
public class Arguments {
    
    private Rule rule = null;
    private List<String> ruleParams = null;
    private File file1 = null;
    private File file2 = null;

    private void setRule(Rule rule) {
        this.rule = rule;
    }

    public Rule getRule() {
        return this.rule;
    }

    void setRuleParameters(List<String> ruleParams) {
        this.ruleParams = ruleParams;
    }

    List<String> getRuleParameters() {
        return this.ruleParams;
    }

    void setFirstFile(File file1) {
        this.file1 = file1;
    }

    public File getFirstFile() {
        return this.file1;
    }

    void setSecondFile(File file2) {
        this.file2 = file2;
    }

    public File getSecondFile() {
        return this.file2;
    }

    public static Arguments checkArguments(String[] args) throws ArgumentException { 
        Arguments mixArgs = new Arguments();
        int index = 0;
        Rule rule = getRuleArgument(args, index, "rule");
        List<String> ruleParams = null;
        if (rule != null) {
            index++;
            ruleParams = getRuleParameters(args, index, rule);
            index += ruleParams.size();
        } else {
            rule = Rule._ADD;
        }
        File file1 = getFileArgument(args, index, "file1");
        File file2 = getFileArgument(args, ++index, "file2");
        mixArgs.setRule(rule);
        mixArgs.setRuleParameters(ruleParams);
        mixArgs.setFirstFile(file1);
        mixArgs.setSecondFile(file2);
        return mixArgs;
    }

    private static Rule getRuleArgument(String[] args, int index, String name) throws ArgumentException {        
        Rule rule = null;
        if (args.length > index) {
            final String ruleString = args[index];
            if (ruleString.startsWith("-")) {
                rule = Rule.findByName(ruleString.substring(1));
                if (rule == null) {
                    throw new ArgumentException(name + " argument is incorrect: " + ruleString);
                }
            }
        }
        return rule;
    }

    private static List<String> getRuleParameters(String[] args, int index, Rule rule) throws ArgumentException {
        List<String> params = new ArrayList<String>();
        Iterator<RuleParam> iterator = rule.getParams().iterator();
        if (iterator.hasNext()) {
            RuleParam param = iterator.next();
            if (args.length > index) {
                String value = args[index];
                if (param.checkValue(value)) {
                    params.add(value);
                    index++;
                } else {
                    if (param.isRequired()) {
                        throw new ArgumentException("[" + param.getName() + "] parameter is incorrect: " + value);    
                    }
                }
            } else {
                if (param.isRequired()) {
                    throw new ArgumentException("[" + param.getName() + "] parameter is required.");    
                }
            }            
        }     
        return params;
    }

    private static File getFileArgument(String[] args, int index, String name) throws ArgumentException {
        File file = null;
        if (args.length > index) {
            String filepath = args[index];
            file = new File(filepath);
            if (file.exists()) {
                if (!file.canRead()) {                    
                    throw new ArgumentException(name + " cannot be read: " + filepath);    
                }
            } else {
                throw new ArgumentException(name + " not found: " + filepath);
            }
        } else {
            throw new ArgumentException(name + " argument missing.");
        }
        return file;
    }

    public static void printUsage() {    
        System.out.println("  ");    
        System.out.println("Usage:");
        System.out.println("  ");
        System.out.println("  mix-them file1 file2");
        System.out.println("  (will generate any file based on file1 and file2)");
        System.out.println("  ");
        System.out.println("  mix-them -[rule] file1 file2");
        System.out.println("  (will generate a file based on the rule)");
        System.out.println("  ");
        System.out.println("  Here are the list of rules");
        for(Rule rule : Rule.values()) {
          System.out.print("  - " + rule.getName());
          for(RuleParam param : rule.getParams()) {
              System.out.print("#"+param.getName());
          }
          System.out.println(": "+rule.getDescription());
        }
        System.out.println("  ");
    }

}

@@ -108,16 +108,104 @@
 o.File;%0A
+import java.nio.file.Files;%0Aimport java.nio.file.LinkOption;%0Aimport java.nio.file.Path;%0A
 import j
@@ -224,16 +224,16 @@
 ayList;%0A
-
 import j
@@ -768,24 +768,31 @@
 %0A    %7D%0A%0A    
+public 
 List%3CString%3E
@@ -1305,19 +1305,20 @@
  rule = 
-get
+find
 RuleArgu
@@ -1458,19 +1458,20 @@
 arams = 
-get
+find
 RulePara
@@ -1615,19 +1615,20 @@
 file1 = 
-get
+find
 FileArgu
@@ -1676,19 +1676,20 @@
 file2 = 
-get
+find
 FileArgu
@@ -1922,27 +1922,28 @@
 static Rule 
-get
+find
 RuleArgument
@@ -2228,21 +2228,8 @@
 ring
-.substring(1)
 );%0A 
@@ -2454,35 +2454,36 @@
 ic List%3CString%3E 
-get
+find
 RuleParameters(S
@@ -3458,19 +3458,20 @@
 ic File 
-get
+find
 FileArgu
@@ -3700,24 +3700,70 @@
     
-if (f
+final Path path = file.toPath();%0A            if (F
 ile
+s
 .exists(
 )) %7B
@@ -3758,16 +3758,47 @@
 .exists(
+path, LinkOption.NOFOLLOW_LINKS
 )) %7B%0A   
@@ -3819,21 +3819,29 @@
 f (!
-file.canRead(
+Files.isReadable(path
 )) %7B
@@ -4945,9 +4945,10 @@
 nt(%22
-#
+ %5B
 %22+pa
@@ -4952,32 +4952,36 @@
 +param.getName()
++%22%5D%22
 );%0A          %7D%0A 

Update Arguments.java