/*
 * @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.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.ranides.assira.collection.arrays.ArrayAllocator;

/**
 *
 * @author ranides
 */
public final class IOStrings {
    
    private IOStrings() { }

	public static void write(Writer writer, String content) throws IOException {
		try {
			writer.write(content);
		} finally {
			writer.close();
		}
	}
	
	public static void write(OutputStream ostream, String content, Charset charset) throws IOException {
		try {	
			write(new OutputStreamWriter(ostream, charset), content);
		} finally {
			ostream.close();
		}
	}
	
	public static void write(File file, String content, Charset charset) throws IOException {
		write(new FileOutputStream(file), content, charset);
	}

    public static String read(Reader reader) throws IOException {
        try {
            char[] buffer = new char[32];
            int r, c = 0;
            while((r = reader.read(buffer, c, buffer.length-c)) > 0) {
                c += r;
                buffer = ArrayAllocator.grow(buffer, c+32);
            }
            return new String(buffer, 0, c);
        } finally {
            reader.close();
        }
    }

    public static String read(InputStream istream, Charset charset) throws IOException {
        try {
            return IOStrings.read(new InputStreamReader(istream, charset));
        } finally {
            istream.close();
        }
    }

    public static String read(File file, Charset charset) throws IOException {
        return read( new FileInputStream(file), charset );
    }

    public static List<String> readLines(Reader ireader) throws IOException {
        ArrayList<String> result = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(ireader)) {
            String line;
            while( null != (line=reader.readLine())) {
                result.add(line);
            }
        }
        result.trimToSize();
        return result;
    }
    
    public static List<String> readLines(InputStream istream, Charset charset) throws IOException {
        return readLines(new BufferedReader(new InputStreamReader(istream, charset)));
    }
    
    public static List<String> readLines(File file, Charset charset) throws IOException {
        return readLines(new FileInputStream(file), charset);
    }
    
    public static void writeLines(Writer iwriter, Iterator<String> content) throws IOException {
        try(BufferedWriter writer = new BufferedWriter(iwriter)) {
            while(content.hasNext()) {
                writer.append(content.next());
                writer.newLine();
            }
        }
    }
    
    public static void writeLines(OutputStream ostream, Charset charset, Iterator<String> content) throws IOException {
        writeLines(new OutputStreamWriter(ostream, charset), content);
    }
    
    public static void writeLines(File file, Charset charset, Iterator<String> content) throws IOException {
        writeLines(new FileOutputStream(file), charset, content);
    }
    
    public static void writeLines(Writer iwriter, Iterable<String> content) throws IOException {
        writeLines(iwriter, content.iterator());
    }
    
    public static void writeLines(OutputStream ostream, Charset charset, Iterable<String> content) throws IOException {
        writeLines(ostream, charset, content.iterator());
    }
    
    public static void writeLines(File file, Charset charset, Iterable<String> content) throws IOException {
        writeLines(file, charset, content.iterator());
    }
    
}
