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

package net.ranides.assira.text;

import net.ranides.assira.io.RIOException;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Scanner;
import net.ranides.assira.io.FileHelper;

/**
 *
 * @author ranides
 */
public final class StringLoader {

    private StringLoader() { }

    public static String fromReader(Reader reader) {
        Scanner scanner = null;
        try {
            scanner = new Scanner(reader);
            return scanner.useDelimiter("\\Z").next();
        } finally {
            FileHelper.close(scanner);
        }
    }

    public static String fromStream(InputStream istream, Charset charset) {
        Scanner scanner = null;
        try {
            scanner = new Scanner(istream, charset.name());
            return scanner.useDelimiter("\\Z").next();
        } finally {
            FileHelper.close(scanner);
        }
    }

    public static String fromStream(InputStream istream) {
        return fromStream(istream, TextEncoding.NIO_UTF8);
    }


    public static String fromFile(File file, Charset charset) throws RIOException {
        try {
            return fromStream( new FileInputStream(file), charset );
        } catch(IOException cause) {
            throw new RIOException(cause);
        }
    }

    public static String fromFile(File file) throws RIOException {
        return fromFile(file, TextEncoding.NIO_UTF8);
    }

    public static String fromFile(String path, Charset charset) throws RIOException {
        return fromFile(new File(path), charset);
    }

    public static String fromFile(String path) throws RIOException {
        return fromFile(path, TextEncoding.NIO_UTF8 );
    }

    /**
     * Ładuje plik ".properties", zachowując kolejność wpisów.
     */
    public static LinkedHashMap<String,String> loadProperties(Reader reader) throws RIOException {
		// @todo (prev # 3) loadProperties spieprzone.
        try {
            LinkedHashMap<String,String> target = new LinkedHashMap<>();
            StreamTokenizer tokenizer =new StreamTokenizer(new BufferedReader(reader));

            // treat space, alpha, numbers and most punctuation as ordinary char
            tokenizer.wordChars(' ', '_');
            tokenizer.commentChar('#');
            tokenizer.whitespaceChars('=', '=');// ignore equal, just separates fields
            tokenizer.eolIsSignificant(true);
            
            while (true) {
                tokenizer.nextToken();
                if (tokenizer.ttype == StreamTokenizer.TT_EOF) { 
                    return target;
                }
                if (tokenizer.ttype == StreamTokenizer.TT_EOL) { 
                    continue; 
                }
                String key = tokenizer.sval.trim();
                tokenizer.nextToken();
                String value = tokenizer.sval.trim();
                target.put(key, value);
            }
        } catch(IOException cause) {
            throw new RIOException(cause);
        } finally {  
            FileHelper.close(reader);
        }
    }
    
    public static List<String> linesFromReader(Reader ireader) throws RIOException {
        BufferedReader reader = null;
        ArrayList<String> result = new ArrayList<>();
        try {
            reader = new BufferedReader(ireader);
            String line;
            while( null != (line=reader.readLine())) {
                result.add(line);
            }
        } catch(IOException cause) {
            throw new RIOException(cause);
        } finally {
            FileHelper.close(reader);
        }
        result.trimToSize();
        return result;
    }
    
    public static List<String> linesFromStream(InputStream istream, Charset charset) throws RIOException {
        return linesFromReader(new BufferedReader(new InputStreamReader(istream, charset)));
    }
    
    public static List<String> linesFromFile(File file, Charset charset) throws RIOException {
        try {
            return linesFromStream(new FileInputStream(file), charset);
        } catch(IOException cause) {
            throw new RIOException(cause);
        }
    }
    
    public static List<String> linesFromFile(String file, Charset charset) throws RIOException {
        return linesFromFile(new File(file), charset);
    }
    
    public static List<String> linesFromFile(File file) throws RIOException {
        return linesFromFile(file, TextEncoding.NIO_UTF8);
    }
    
    public static List<String> linesFromFile(String file) throws RIOException {
        return linesFromFile(file, TextEncoding.NIO_UTF8);
    }
    
}
