package com.s13g.aoc;

import com.s13g.FileUtil;

import java.io.IOException;
import java.util.Locale;

/**
 * Runs all the Advent of Code puzzle solvers.
 */
public class PuzzleRunner {
  private static final String NEW_TMPL = "(%s)[ NEW ] - %s --> %s";
  private static final String OK_TMPL = "(%s)[ OK ]  - %s";
  private static final String FAIL_TMPL = "(%s)[FAIL]  -  %s --> %s (but should be %s)";


  public static void main(String[] args) throws IOException {
    for (PuzzleSetup setup : Setups.getPuzzles()) {
      String input = FileUtil.readAsString(setup.inputFileName);
      String className = setup.puzzle.getClass().getSimpleName();
      Puzzle.Solution solution = setup.puzzle.solve(input);
      printResult("A", className, setup.expectedResultA, solution.solutionA);
      printResult("B", className, setup.expectedResultB, solution.solutionB);
    }
  }

  private static void printResult(String prefix, String className, String expected, String result) {
    if (expected == null) {
      print(NEW_TMPL, prefix, className, result);
    } else if (expected.equals(result)) {
      print(OK_TMPL, prefix, className);
    } else {
      print(FAIL_TMPL, prefix, className, result, expected);
    }
  }

  private static void print(String format, Object... vars) {
    System.out.println(String.format(Locale.US, format, vars));
  }

  static class PuzzleSetup {
    final String inputFileName;
    final Puzzle puzzle;
    final String expectedResultA;
    final String expectedResultB;

    PuzzleSetup(String inputFileName,
                        Puzzle puzzle,
                        String expectedResultA,
                        String expectedResultB) {
      this.inputFileName = inputFileName;
      this.puzzle = puzzle;
      this.expectedResultA = expectedResultA;
      this.expectedResultB = expectedResultB;
    }

    PuzzleSetup(String inputFileName,
                Puzzle puzzle,
                long expectedResultA,
                long expectedResultB) {
      this.inputFileName = inputFileName;
      this.puzzle = puzzle;
      this.expectedResultA = String.valueOf(expectedResultA);
      this.expectedResultB = String.valueOf(expectedResultB);
    }
  }
}

@@ -43,16 +43,37 @@
 eUtil;%0A%0A
+import java.io.File;%0A
 import j
@@ -92,16 +92,16 @@
 eption;%0A
-
 import j
@@ -482,16 +482,60 @@
 ption %7B%0A
+    File dataDir = getDataDirectory(args);%0A%0A
     for 
@@ -621,16 +621,34 @@
 sString(
+new File(dataDir, 
 setup.in
@@ -655,24 +655,25 @@
 putFileName)
+)
 ;%0A      Stri
@@ -1359,24 +1359,24 @@
 ... vars) %7B%0A
-
     System.o
@@ -1432,16 +1432,402 @@
 );%0A  %7D%0A%0A
+  private static File getDataDirectory(String args%5B%5D) %7B%0A    if (args.length != 1) %7B%0A      throw new IllegalArgumentException(%22One argument expected: Data directory.%22);%0A    %7D%0A    File dataDir = new File(args%5B0%5D);%0A    if (!dataDir.isDirectory()) %7B%0A      throw new IllegalArgumentException(%22Argument is not a valid directory: %22 + dataDir.getAbsolutePath());%0A    %7D%0A    return dataDir;%0A  %7D%0A%0A
   static

Add data dir parameter to PuzzleRunner.