package org.coderepos.nori090.df;

import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.concurrent.ConcurrentLinkedQueue;

import junit.framework.Assert;

import org.junit.Test;

public class DFCheck {
    static File f = new File( "target/" );

    @Test
    public void testDf()
        throws Exception {
        // String jar = build();
        String jar = getJarName();
        String path = f.getAbsolutePath();
        path = path.endsWith( "/" ) || path.endsWith( "\\" ) ? path.concat( jar ) : path.concat( "/" ).concat( jar );
        File jarfile = new File( path );
        Runtime runtime = Runtime.getRuntime();
        ConcurrentLinkedQueue<String> queue = sendData( 0 );
        final Process p = runtime.exec( "java -jar " + jarfile.getAbsolutePath() );
        PrintStream out = new PrintStream( p.getOutputStream(), false, "sjis" );
        BufferedReader in = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
        Thread t = new Thread() {
            @Override
            public void run() {
                out( p.getErrorStream(), true );
            }
        };
        t.start();
        String s = null;
        boolean first = true;
        while ( ( s = in.readLine() ) != null ) {
            if ( first ) {
                Assert.assertTrue( s.startsWith( "hello" ) );
                first = false;
            }
            while ( !queue.isEmpty() ) {
                String cmd = queue.poll();
                out.println( cmd );
                out.flush();
                System.out.println( cmd );
                if ( cmd.startsWith( "turn" ) ) {
                    break;
                }
            }
        }
    }

    static ConcurrentLinkedQueue<String> sendData( int number ) {
        ConcurrentLinkedQueue<String> set = new ConcurrentLinkedQueue<String>();
        try {
            BufferedReader br =
                new BufferedReader(
                                    new InputStreamReader(
                                                           DFCheck.class.getResourceAsStream( "/org/coderepos/nori090/df/log.dat" ),
                                                           "sjis" ) );
            String s = null;
            while ( ( s = br.readLine() ) != null ) {
                if ( s.startsWith( "send " + number + ":" ) ) {
                    s = s.replaceAll( "send " + number + ": ", "" );
                    set.add( s );
                }
            }
            br.close();
        }
        catch ( Exception e ) {
            e.printStackTrace();
        }
        return set;
    }

    static String build() {
        try {
            Runtime runtime = Runtime.getRuntime();
            Process p = runtime.exec( "build.bat" );
            out( p.getInputStream(), false );
            out( p.getErrorStream(), true );
        }
        catch ( IOException e ) {
            e.printStackTrace();
        }
        return getJarName();
    }

    static String getJarName() {
        String[] files = f.list( new FilenameFilter() {
            @Override
            public boolean accept( File dir, String name ) {
                if ( name.toLowerCase().endsWith( "-bin.jar" ) ) {
                    return true;
                }
                return false;
            }
        } );
        if ( files != null && files.length != 0 ) {
            return files[0];
        }
        return null;
    }

    static void out( InputStream in, boolean isError ) {
        BufferedReader br = null;
        try {
            br = new BufferedReader( new InputStreamReader( in ) );
            String s = null;
            while ( ( s = br.readLine() ) != null ) {
                if ( isError ) {
                    System.err.println( s );
                }
                else {
                    System.out.println( s );
                }
            }
        }
        catch ( Exception e ) {
            e.printStackTrace();
        }
        finally {
            try {
                br.close();
            }
            catch ( IOException e ) {
            }
        }
    }

}
