/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.text;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class IOStringsTest {
    
	private static final String TEXT = "źrebię skacze po łące patrząc na słońce";

    @Test
    public void testFromReader() throws IOException {
        String inp1 = "Hello world";
        String out1 = IOStrings.read(new StringReader(inp1));
        assertEquals(inp1, out1);
        
        String inp2 = random(10247) ;
        String out2 = IOStrings.read(new StringReader(inp2));
        assertEquals(inp2, out2);
    }
    
    @Test
    public void testFromStream() throws IOException {
        ByteArrayInputStream istream1 = new ByteArrayInputStream(TEXT.getBytes(Charsets.UTF8));
        ByteArrayInputStream istream2 = new ByteArrayInputStream(TEXT.getBytes(Charsets.PL_WINDOWS));
        
        assertNotEquals(TEXT, IOStrings.read(istream1, Charsets.PL_WINDOWS));
        istream1.reset();
        assertEquals(TEXT, IOStrings.read(istream1, Charsets.UTF8));
        
        assertNotEquals(TEXT, IOStrings.read(istream2, Charsets.UTF8));
        istream2.reset();
        assertEquals(TEXT, IOStrings.read(istream2, Charsets.PL_WINDOWS));
    }
    
    @Test
    public void testLinesFromReader() throws IOException {
        String c1 = "1\n2\n3\n4\n5";
        String c2 = "1\n2\n3\n4\n5\n";
        List<String> expected = Arrays.asList("1","2", "3", "4", "5");
        
        assertEquals(expected, IOStrings.readLines(new StringReader(c1)));
        assertEquals(expected, IOStrings.readLines(new StringReader(c2)));
    }
    
    @Test
    public void testLinesFromStream_UTF8() throws IOException {
        ByteArrayInputStream s1 = new ByteArrayInputStream("słońce\nźrebię\nłąka\ndom".getBytes(Charsets.UTF8));
        ByteArrayInputStream s2 = new ByteArrayInputStream("słońce\nźrebię\nłąka\ndom\n".getBytes(Charsets.UTF8));
        List<String> expected = Arrays.asList("słońce", "źrebię", "łąka", "dom");
        
        assertEquals(expected, IOStrings.readLines(s1, Charsets.UTF8));
        assertEquals(expected, IOStrings.readLines(s2, Charsets.UTF8));
    }
    
    @Test
    public void testLinesFromStream_CS() throws IOException {
        ByteArrayInputStream s1 = new ByteArrayInputStream("słońce\nźrebię\nłąka\ndom".getBytes(Charsets.PL_DOS));
        ByteArrayInputStream s2 = new ByteArrayInputStream("słońce\nźrebię\nłąka\ndom\n".getBytes(Charsets.PL_DOS));
        List<String> expected = Arrays.asList("słońce", "źrebię", "łąka", "dom");
        
        assertEquals(expected, IOStrings.readLines(s1, Charsets.PL_DOS));
        assertEquals(expected, IOStrings.readLines(s2, Charsets.PL_DOS));
    }
	
	@Test
    public void testLinesFromFile_CS() throws IOException {
		File file1 = File.createTempFile("StringIO.LFF1", ".txt");
		File file2 = File.createTempFile("StringIO.LFF1", ".txt");
		
		IOStrings.write(file1, "słońce\nźrebię\nłąka\ndom", Charsets.PL_DOS);
		IOStrings.write(file2, "słońce\nźrebię\nłąka\ndom\n", Charsets.PL_DOS);
		
        List<String> expected = Arrays.asList("słońce", "źrebię", "łąka", "dom");
        
        assertEquals(expected, IOStrings.readLines(file1, Charsets.PL_DOS));
        assertEquals(expected, IOStrings.readLines(file2, Charsets.PL_DOS));
    }
	
	@Test
	public void testToWriter() throws IOException {
		StringWriter writer = new StringWriter();
		IOStrings.write(writer, TEXT);
		assertEquals(TEXT, writer.toString());
	}
	
	@Test
	public void testToStream() throws IOException {
		ByteArrayOutputStream ostream1 = new ByteArrayOutputStream();
		IOStrings.write(ostream1, TEXT, Charsets.PL_DOS);
		assertArrayEquals(ostream1.toByteArray(), TEXT.getBytes(Charsets.PL_DOS));
		
		ByteArrayOutputStream ostream2 = new ByteArrayOutputStream();
		IOStrings.write(ostream2, TEXT, Charsets.PL_ISO);
		assertArrayEquals(ostream2.toByteArray(), TEXT.getBytes(Charsets.PL_ISO));
	}
	
	@Test
	public void testToFile() throws IOException {
		File file1 = File.createTempFile("StringIOF1", ".txt");
		IOStrings.write(file1, TEXT, Charsets.PL_DOS);
		
		assertNotEquals(TEXT, IOStrings.read(file1, Charsets.PL_ISO));
		assertEquals(TEXT, IOStrings.read(file1, Charsets.PL_DOS));
		
		File file2 = File.createTempFile("StringIOF1", ".txt");
		IOStrings.write(file2, TEXT, Charsets.PL_ISO);
		
		assertNotEquals(TEXT, IOStrings.read(file2, Charsets.PL_DOS));
		assertEquals(TEXT, IOStrings.read(file2, Charsets.PL_ISO));
	}

    @Test
    public void testLinesToFile() throws Exception {
        File file1 = File.createTempFile("StringIOF2", ".txt");
        List<String> expected = Arrays.asList("1","2", "3", "4", "5");

        IOStrings.writeLines(file1, Charsets.UTF8, expected);

        assertEquals(expected, IOStrings.readLines(file1, Charsets.UTF8));
    }

    @Test
    public void testLinesToWriter() throws Exception {
        StringWriter writer = new StringWriter();
        List<String> expected = Arrays.asList("1", "2", "3", "4", "5");

        IOStrings.writeLines(writer, expected);

        assertEquals(expected, IOStrings.readLines(new StringReader(writer.toString())));
    }

    @Test
    public void testLinesToStream() throws Exception {
        ByteArrayOutputStream ostream = new ByteArrayOutputStream();
        List<String> expected = Arrays.asList("1", "2", "3", "4", "5");

        IOStrings.writeLines(ostream, Charsets.UTF8, expected);
        assertEquals(expected, IOStrings.readLines(new ByteArrayInputStream(ostream.toByteArray()), Charsets.UTF8));
    }

    private String random(int size) {
        Random rand = new Random(777);
        char[] c = new char[size];
        for(int i=0; i<size; i++) {
            c[i] = (char)(' ' + rand.nextInt(64));
        }
        return new String(c);
    }
}
