package net.heartshield.data;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;

/**
 * @author David Madl (git@abanbytes.eu)
 * @date 2017-04-10
 */
public class FileUtil {
    public static final String PERSISTENT_DATA_DIR = "/hsh/data"; // data directory on SD card
    static final String PERSISTENT_APP_INFO_DIR = "/hsh";
    static final String PERSISTENT_APP_INFO = "app_id_info.b";
    static final String MEASUREMENT_CACHE = "measurements.json";

    private File mStorageDirectory;

    public FileUtil(File storageDirectory) {
        mStorageDirectory = storageDirectory;
    }

    public File getStorageDirectory() {
        return mStorageDirectory;
    }

    public void makeDirectories(String sdcardPath) {
        String dirName = mStorageDirectory.getAbsolutePath() + sdcardPath;
        File dir = new File(dirName);
        if(!dir.exists())
            if(!dir.mkdirs())
                throw new RuntimeException("could not create dir in " + dirName);
    }

    public static String readFileString(InputStream is) throws IOException {
        BufferedReader buf = new BufferedReader(new InputStreamReader(is));
        String line = buf.readLine();
        StringBuilder sb = new StringBuilder();
        while (line != null) {
            sb.append(line).append("\n");
            line = buf.readLine();
        }
        buf.close();
        return sb.toString();
    }

    public static byte[] readFileBytes(InputStream is) throws IOException {
        byte[] buf = new byte[1024];
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        int len;
        while((len = is.read(buf)) != -1)
            data.write(buf, 0, len);
        return data.toByteArray();
    }

    public String readDataFileString(String relFileName) throws IOException {
        File f = new File(mStorageDirectory.getAbsolutePath() + FileUtil.PERSISTENT_DATA_DIR, relFileName);
        return readFileString(new FileInputStream(f));
    }

    public byte[] readDataFileBytes(String relFileName) throws IOException {
        File f = new File(mStorageDirectory.getAbsolutePath() + FileUtil.PERSISTENT_DATA_DIR, relFileName);
        return readFileBytes(new FileInputStream(f));
    }

    public void writeDataFileContents(String relFileName, String contents) throws IOException {
        File info = new File(mStorageDirectory.getAbsolutePath() + FileUtil.PERSISTENT_DATA_DIR, relFileName);
        FileOutputStream os = new FileOutputStream(info);
        os.write(contents.getBytes());
        os.close();
    }

    public void writeDataFileContents(String relFileName, byte[] contents) throws IOException {
        File info = new File(mStorageDirectory.getAbsolutePath() + FileUtil.PERSISTENT_DATA_DIR, relFileName);
        FileOutputStream os = new FileOutputStream(info);
        os.write(contents);
        os.close();
    }

    public boolean dataFileExists(String relFileName) {
        File info = new File(mStorageDirectory.getAbsolutePath() + FileUtil.PERSISTENT_DATA_DIR, relFileName);
        return info.exists();
    }

    boolean removeDataFile(String relFileName) throws IOException {
        File info = new File(mStorageDirectory.getAbsolutePath() + FileUtil.PERSISTENT_DATA_DIR, relFileName);
        return info.delete();
    }

    public File[] listDataDir(final String fileSuffix) {
        File dataDir = new File(mStorageDirectory.getAbsolutePath() + FileUtil.PERSISTENT_DATA_DIR);
        File[] files = dataDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(fileSuffix);
            }
        });
        Arrays.sort(files, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                return o1.getAbsolutePath().compareTo(o2.getAbsolutePath());
            }
        });
        return files;
    }
}
