package com.github.violetlaw.citegen;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.List;

import com.github.violetlaw.citegen.Citation.CitationRequest;
import com.github.violetlaw.citegen.Citation.CitationRequest.Builder;
import com.github.violetlaw.citegen.TextOutput.TextContainer;
import com.google.auto.value.AutoValue;
import com.google.common.collect.Lists;
import com.google.protobuf.util.JsonFormat;
import com.google.protobuf.util.JsonFormat.Parser;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class CitationGeneratorTest {

  // TODO(nnaze): Implement parameterized tests at this point.

  private static Path GOLDEN_TESTS = Paths.get("src/test/resources/goldentests");

  private static Path INPUT = GOLDEN_TESTS.resolve("input");
  private static Path OUTPUT = GOLDEN_TESTS.resolve("output");

  @Parameters
  // TODO(nnaze): Also paramaterize the test name.
  public static Iterable<GoldenTestData> data() throws IOException {
    return getTestCases();
  }

  final private GoldenTestData data;

  public CitationGeneratorTest(GoldenTestData data) {
    this.data = data;
  }

  @Test
  public void testGoldenTestData() throws IOException {
  	verifyInputOutput(data.input(), data.output());
  }

  private void verifyInputOutput(CitationRequest request, TextContainer outputText) {
		// TODO(nnaze): Implement input/output test here.

	}

	@AutoValue
  public static abstract class GoldenTestData {
    static GoldenTestData create(Path inputPath, Path outputPath) {
      return new AutoValue_CitationGeneratorTest_GoldenTestData(inputPath, outputPath);
    }

    abstract Path inputPath();

    abstract Path outputPath();
    
    CitationRequest input() throws IOException {
    	Parser parser = JsonFormat.parser();
    	CitationRequest.Builder builder = CitationRequest.newBuilder();
    	parser.merge(new FileReader(inputPath().toFile()), builder);
    	return builder.build();
    }
    
    TextContainer output() throws IOException {
    	Parser parser = JsonFormat.parser();
    	TextContainer.Builder builder = TextContainer.newBuilder();
    	parser.merge(new FileReader(outputPath().toFile()), builder);
    	return builder.build();
    }
  }

  private static List<GoldenTestData> getTestCases() throws IOException {
    List<GoldenTestData> testCases = Lists.newLinkedList();
    DirectoryStream<Path> inputPaths = Files.newDirectoryStream(INPUT, "*.json");
    for (Path inputPath : inputPaths) {
      Path outputPath = OUTPUT.resolve(inputPath.getFileName());

      testCases.add(GoldenTestData.create(inputPath, outputPath));
    }

    return testCases;
  }
}

@@ -1252,59 +1252,22 @@
 ters
-%0A  // TODO(nnaze): Also paramaterize the test name.
+(name = %22%7B0%7D%22)
 %0A  p
@@ -1549,17 +1549,18 @@
 ion %7B%0A  
-%09
+  
 verifyIn
@@ -1694,10 +1694,12 @@
 ) %7B%0A
-%09%09
+    
 // T
@@ -1749,13 +1749,15 @@
 e.%0A%0A
-%09%7D%0A%0A%09
+  %7D%0A%0A  
 @Aut
@@ -2038,20 +2038,16 @@
 Path();%0A
-    
 %0A    Cit
@@ -2084,33 +2084,34 @@
 Exception %7B%0A    
-%09
+  
 Parser parser = 
@@ -2135,17 +2135,18 @@
 ();%0A    
-%09
+  
 Citation
@@ -2197,33 +2197,34 @@
 wBuilder();%0A    
-%09
+  
 parser.merge(new
@@ -2264,33 +2264,34 @@
 , builder);%0A    
-%09
+  
 return builder.b
@@ -2304,20 +2304,16 @@
 ;%0A    %7D%0A
-    
 %0A    Tex
@@ -2357,17 +2357,18 @@
 n %7B%0A    
-%09
+  
 Parser p
@@ -2400,17 +2400,18 @@
 ();%0A    
-%09
+  
 TextCont
@@ -2466,17 +2466,18 @@
 ();%0A    
-%09
+  
 parser.m
@@ -2538,9 +2538,10 @@
     
-%09
+  
 retu
@@ -2565,16 +2565,168 @@
 );%0A    %7D
+%0A%0A    @Override%0A    public String toString() %7B%0A      return String.format(%22%25s input: %25s output: %25s%22, super.toString(), inputPath(), outputPath());%0A    %7D
 %0A  %7D%0A%0A  

parameterize the test name