/**
 * 
 */
package pt.utl.ist.scripts.utils;

import java.io.BufferedInputStream;
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.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import pt.utl.ist.scripts.dataTransferObject.IFileLine;

/**
 * 
 * This class reads a file and loads it data to a collection of the
 * correspondent DTO. That DTO must implement the interface IFileLine
 * 
 * @author - Shezad Anavarali (shezad@ist.utl.pt)
 * 
 */
public class DataLoaderFromFile<T> {

    public Collection<T> load(Class<T> clazz, String fileFullPathAndname) {

        final String[] data = readFile(fileFullPathAndname);

        Collection<T> result = new ArrayList<T>(data.length);

        for (String dataLine : data) {

            T t = instanciateType(clazz);

            boolean shouldAdd = ((IFileLine) t).fillWithFileLineData(dataLine);

            if (shouldAdd) {
                result.add(t);
            }

        }

        return result;
    }

    public Map<String, T> loadToMap(Class<T> clazz, String fileFullPathAndname) {

        final String[] data = readFile(fileFullPathAndname);

        Map<String, T> result = new HashMap<String, T>(data.length);

        for (String dataLine : data) {

            T t = instanciateType(clazz);

            boolean shouldAdd = ((IFileLine) t).fillWithFileLineData(dataLine);

            if (shouldAdd) {
                result.put(((IFileLine) t).getUniqueKey(), t);
            }

        }

        return result;
    }

    private T instanciateType(Class<T> clazz) {
        T t = null;
        try {
            t = clazz.newInstance();

        } catch (InstantiationException e) {
            throw new RuntimeException(e);

        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);

        }
        return t;
    }

    public static String[] readFile(String fileFullPathAndname) {
        String fileContents = null;
        try {
            char[] buffer = new char[(int) new File(fileFullPathAndname).length()];
            InputStream is = new BufferedInputStream(new FileInputStream(fileFullPathAndname));
            Reader reader = new InputStreamReader(is, "UTF-8");

            reader.read(buffer);
            fileContents = new String(buffer);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }

        final String[] data = fileContents.split("\n");

        return data;
    }
}
