package com.noticeditorteam.noticeditor.io;

import gcardone.junidecode.Junidecode;
import java.io.*;
import java.net.URLEncoder;
import org.json.JSONException;
import org.json.JSONObject;

public final class IOUtil {

    private static final int FILENAME_LIMIT = 60;
    private static final String NEW_LINE = System.lineSeparator();

    public static String readContent(File file) throws IOException {
        return stringFromStream(new FileInputStream(file));
    }

    public static void writeContent(File file, String content) throws IOException {
        try (OutputStream os = new FileOutputStream(file);
             Writer writer = new OutputStreamWriter(os, "UTF-8")) {
            writer.write(content);
        }
    }

    public static void writeContent(File file, byte[] content) throws IOException {
        try (OutputStream os = new FileOutputStream(file)) {
            os.write(content);
        }
    }

    public static void writeJson(File file, JSONObject json) throws IOException, JSONException {
        try (OutputStream os = new FileOutputStream(file);
             Writer writer = new OutputStreamWriter(os, "UTF-8")) {
            json.write(writer);
        }
    }

    public static void removeDirectory(File directory) {
        if (directory.isFile() || !directory.exists())
            return;
        removeDirectoryHelper(directory);
    }

    private static void removeDirectoryHelper(File file) {
        if (file.isDirectory()) {
            for (File f : file.listFiles()) {
                removeDirectoryHelper(f);
            }
        }
        file.delete();
    }

    public static String sanitizeFilename(String name) {
        if (name == null || name.isEmpty())
            return "empty";

        String newName = name;
        // Quick transliteration
        newName = Junidecode.unidecode(newName);
        // Convert non-ascii chars to char code
        try {
            newName = URLEncoder.encode(newName, "UTF-8");
        } catch (UnsupportedEncodingException ex) {
        }
        // Allow only english chars, numbers and some specific symbols
        newName = newName.toLowerCase().replaceAll("[^a-z0-9._\\(\\)]", "_");
        // Limit filename length
        if (newName.length() > FILENAME_LIMIT) {
            newName = newName.substring(0, FILENAME_LIMIT);
        }
        return newName;
    }

    public static InputStream toStream(String content) throws IOException {
        return toStream(content, "UTF-8");
    }

    public static InputStream toStream(String content, String charset) throws IOException {
        return new ByteArrayInputStream(content.getBytes(charset));
    }

    public static String stringFromStream(InputStream stream) throws IOException {
        return stringFromStream(stream, "UTF-8");
    }

    public static String stringFromStream(InputStream stream, String charset) throws IOException {
        final StringBuilder result = new StringBuilder();
        try (Reader isr = new InputStreamReader(stream, charset);
             BufferedReader reader = new BufferedReader(isr)) {
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line).append(NEW_LINE);
            }
        }
        return result.toString();
    }

    public static void copy(InputStream is, OutputStream os) throws IOException {
        final int bufferSize = 4096;
        final byte[] buffer = new byte[bufferSize];
        int readed = 0;
        while ((readed = is.read(buffer, 0, bufferSize)) != -1) {
            os.write(buffer, 0, readed);
        }
    }
}

@@ -123,16 +123,105 @@
 ncoder;%0A
+import java.util.Collections;%0Aimport java.util.List;%0Aimport java.util.stream.Collectors;%0A
 import o
@@ -354,75 +354,8 @@
  60;
-%0A    private static final String NEW_LINE = System.lineSeparator();
 %0A%0A  
@@ -2941,107 +2941,618 @@
 nal 
-StringBuilder result = new StringBuilder();%0A        try (Reader
+ByteArrayOutputStream result = new ByteArrayOutputStream();%0A        copy(stream, result);%0A        stream.close();%0A        return result.toString(%22UTF-8%22);%0A    %7D%0A%0A    public static boolean isResourceExists(String resource) %7B%0A        try (InputStream is = IOUtil.class.getResourceAsStream(resource)) %7B%0A            return
  is
-r
  
+!
 = n
-ew InputStreamReader(stream,
+ull;%0A        %7D catch (IOException ioe) %7B%0A            return false;%0A        %7D%0A    %7D%0A%0A    public static List%3CString%3E linesFromResource(String resource) %7B%0A        return linesFromResource(resource, %22UTF-8%22);%0A    %7D%0A%0A    public static List%3CString%3E linesFromResource(String resource, String
  cha
@@ -3556,17 +3556,18 @@
 charset)
-;
+ %7B
 %0A       
@@ -3571,87 +3571,203 @@
     
-     BufferedReader reader = new BufferedReader(isr)) %7B%0A            String line
+try (InputStream is = IOUtil.class.getResourceAsStream(resource)) %7B%0A            return linesFromStream(is, charset);%0A        %7D catch (IOException ioe) %7B%0A            return Collections.emptyList()
 ;%0A  
@@ -3776,135 +3776,428 @@
     
+%7D%0A
     
-while ((line = reader.readLine()) != null) %7B%0A                result.append(line).append(NEW_LINE);%0A            %7D%0A    
+%7D%0A%0A    public static List%3CString%3E linesFromStream(InputStream stream) throws IOException %7B%0A        return linesFromStream(stream, %22UTF-8%22);%0A    %7D%0A%0A    public static List%3CString%3E linesFromStream(InputStream stream, String charset) throws IOException %7B%0A        if (stream == null) return Collections.emptyList();%0A        try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, charset))) %7B%0A
     
-%7D%0A
     
@@ -4213,24 +4213,60 @@
 n re
-sult.toString();
+ader.lines().collect(Collectors.toList());%0A        %7D
 %0A   
@@ -4386,12 +4386,12 @@
 e = 
-4096
+8192
 ;%0A  
@@ -4462,12 +4462,8 @@
 aded
- = 0
 ;%0A  

Add functions to IOUtil, speed up reading content in stringFromStream