/*
 * Copyright 2017 Volker Berlin (i-net software)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.inetsoftware.jwebassembly;

import static org.junit.Assert.*;

import java.io.File;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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

/**
 * Test to compile a list of single sample files.
 * 
 * @author Volker Berlin
 *
 */
@RunWith( Parameterized.class )
public class SampleCompileTest {

    private final String testName;
    private final File classFile;

    public SampleCompileTest( String testName, File classFile ) {
        this.testName = testName;
        this.classFile = classFile;
    }

    @Parameters( name = "{0}" )
    public static List<Object[]> params() throws Exception {
        ArrayList<Object[]> params = new ArrayList<>();
        URL url = SampleCompileTest.class.getResource( "samples" );
        File dir = new File( url.toURI() );
        int baseLength = dir.getPath().length() + 1;
        params( params, dir, baseLength );
        return params;
    }

    private static void params( ArrayList<Object[]> params, File dir, int baseLength ) {
        for( File file : dir.listFiles() ) {
            if( file.getName().endsWith( ".class" ) ) {
                String path = file.getPath();
                params.add( new Object[] { path.substring( baseLength, path.length() - 6 ), file } );
            } else if( file.isDirectory() ) {
                params( params, file, baseLength );
            }
        }
    }

    @Test
    public void compileToText() throws Exception {
        URL url = SampleCompileTest.class.getResource( "samples/" + testName + ".wat" );
        File watFile = new File( url.toURI() );
        String expected = new String( Files.readAllBytes( watFile.toPath() ) );
        JWebAssembly webAsm = new JWebAssembly();
        webAsm.addFile( classFile );
        String text = webAsm.compileToText();
        assertEquals( expected, text );
    }

    @Test
    public void compileToBinary() throws Exception {
        JWebAssembly webAsm = new JWebAssembly();
        webAsm.addFile( classFile );
        byte[] actual = webAsm.compileToBinary();
        byte[] expected = {0, 97, 115, 109, 1, 0, 0, 0};
        actual = Arrays.copyOf( actual, 8 );
        assertArrayEquals( expected, actual );
    }

    @Test
    public void npe() throws Exception {
        JWebAssembly webAsm = new JWebAssembly();
        webAsm.addFile( classFile );
        try {
            webAsm.compileToBinary( (OutputStream)null );
            fail();
        } catch( WasmException ex ) {
            // expected
            assertTrue( "" + ex.getCause(), ex.getCause() instanceof NullPointerException );
        }
    }


//    @Test
//    public void compileToBinary() throws Exception {
//        URL url = SampleCompileTest.class.getResource( "samples/" + testName + ".wasm" );
//        File wasmFile = new File( url.toURI() );
//        byte[] expected = Files.readAllBytes( wasmFile.toPath() );
//        JWebAssembly webAsm = new JWebAssembly();
//        webAsm.addFile( classFile );
//        byte[] actual = webAsm.compileToBinary();
//        System.err.println(Arrays.toString( expected ));
//        System.err.println(Arrays.toString( actual ));
//        assertArrayEquals( expected, actual );
//    }
}

@@ -703,16 +703,44 @@
 o.File;%0A
+import java.io.IOException;%0A
 import j
@@ -3473,19 +3473,16 @@
 %0A    %7D%0A%0A
-%0A//
     @Tes
@@ -3483,18 +3483,16 @@
   @Test%0A
-//
     publ
@@ -3495,39 +3495,37 @@
 public void 
-compileToBinary
+binaryIoError
 () throws Ex
@@ -3534,26 +3534,24 @@
 ption %7B%0A
-//
         
 URL url 
@@ -3546,151 +3546,420 @@
     
-URL url = SampleCompileTest.class.getResource( %22samples/%22 + testName + %22.wasm%22 );%0A//        File wasmFile = new File( url.toURI()
+JWebAssembly webAsm = new JWebAssembly();%0A        webAsm.addFile( classFile );%0A        File tempDir = Files.createTempDirectory( null ).toFile(); %0A        try %7B%0A            webAsm.compileToBinary( tempDir );%0A            fail();%0A        %7D catch( WasmException ex ) %7B%0A            // expected%0A            tempDir.delete();%0A            assertTrue( %22%22 + ex.getCause(), ex.getCause() instanceof IOException
  );%0A
-//
         
 byte
@@ -3958,69 +3958,128 @@
     
-byte%5B%5D expected = Files.readAllBytes( wasmFile.toPath() );%0A//
+    assertEquals( -1, ex.getLineNumber() );%0A        %7D%0A    %7D%0A%0A    @Test%0A    public void textIoError() throws Exception %7B%0A
     
@@ -4120,26 +4120,24 @@
 Assembly();%0A
-//
         webA
@@ -4161,26 +4161,24 @@
 File );%0A
-//
         
 byte%5B%5D a
@@ -4173,60 +4173,155 @@
     
-byte%5B%5D actual = webAsm.compileToBinary
+File tempDir = Files.createTempDirectory( null ).toFile(); %0A        try %7B%0A            webAsm.compileToText( tempDir );%0A            fail
 ();%0A
-//
         
 Syst
@@ -4320,67 +4320,100 @@
     
-System.err.println(Arrays.toString( expected )
+%7D catch( WasmException ex ) %7B%0A            // expected%0A            tempDir.delete(
 );%0A
-//
         
 Syst
@@ -4412,57 +4412,88 @@
     
-System.err.println(Arrays.toString( actual ));%0A//
+    assertTrue( %22%22 + ex.getCause(), ex.getCause() instanceof IOException );%0A    
     
@@ -4498,37 +4498,32 @@
       assert
-Array
 Equals( 
 expected, ac
@@ -4514,30 +4514,44 @@
 ls( 
-expected, actual );%0A//
+-1, ex.getLineNumber() );%0A        %7D%0A
     

add i/O error tests