package ev3dev.utils;

import org.slf4j.Logger;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * The class responsible to interact with Sysfs on EV3Dev
 * 
 * @author Juan Antonio Breña Moral
 *
 */
public class Sysfs {

    private static final Logger log = org.slf4j.LoggerFactory.getLogger(Sysfs.class);

    /**
	 * Write a value in a file.
	 * 
	 * @param filePath File path
	 * @param value value to write
	 * @return A boolean value if the operation was written or not.
	 */
	public static boolean writeString(final String filePath, final String value) {
		if(log.isTraceEnabled())
			log.trace("echo " + value + " > " + filePath);
		try {
			final File file = new File(filePath);
			if(file.canWrite()) {
				//TODO Review if it possible to improve
				PrintWriter out = new PrintWriter(file);
				out.println(value);
				out.flush();
				out.close();
			//TODO Review
			}else {
				log.error("File: '{}' without write permissions.", filePath);
				return false;
			}
		} catch (IOException e) {
            log.error(e.getLocalizedMessage(), e);
			return false;
		}
		return true;
	}
	
	public static boolean writeInteger(final String filePath, final int value) {
		return writeString(filePath, new StringBuilder().append(value).toString());
	}
	
	/**
	 * Read an Attribute in the Sysfs with containing String values
	 * @param filePath path
	 * @return value from attribute
	 */
	public static String readString(final String filePath) {
		if(log.isTraceEnabled())
			log.trace("cat " + filePath);
		try {
			final Path path = Paths.get(filePath);
			if(existFile(path) && Files.isReadable(path)){
				final String result = Files.readAllLines(path, Charset.forName("UTF-8")).get(0);
				if(log.isTraceEnabled())
					log.trace("value: {}", result);
				return result;
			}
			throw new IOException("Problem reading path: " + filePath);
		} catch (IOException e) {
			log.error(e.getLocalizedMessage(), e);
			throw new RuntimeException("Problem reading path: " + filePath, e);
		}
	}
	
	/**
	 * Read an Attribute in the Sysfs with containing Integer values
	 * @param filePath path
	 * @return value from attribute
	 */
	public static int readInteger(final String filePath) {
		return Integer.parseInt(readString(filePath));
	}
	
	public static float readFloat(final String filePath) {
		return Float.parseFloat(readString(filePath));
	}
	
	/**
	 * 
	 * @param filePath path
	 * @return an List with options from a path
	 */
	public static List<File> getElements(final String filePath) {
		final File f = new File(filePath);
		if(existPath(filePath) && (f.listFiles().length > 0)) {
            return new ArrayList<>(Arrays.asList(f.listFiles()));
		}else {
			throw new RuntimeException("The path doesn't exist: " + filePath);
		}
	}

	/**
	 * This method is used to detect folders in /sys/class/
	 *
	 * @param filePath path
	 * @return boolean
	 */
	public static boolean existPath(final String filePath){
		if(log.isTraceEnabled())
			log.trace("ls " + filePath);
		final File f = new File(filePath);
        return f.exists() && f.isDirectory();
    }

	public static boolean existFile(Path pathToFind) {
		return Files.exists(pathToFind);
	}

	public static boolean writeBytes(final String path, final byte[] value) {
        final File file = new File(path);
		try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) {
			out.write(value);
			out.flush();
			out.close();
		} catch (IOException e) {
			throw new RuntimeException("Unable to draw the LCD", e);
		}
		return true;
	}

}

@@ -176,16 +176,57 @@
 .Paths;%0A
+import java.nio.file.StandardOpenOption;%0A
 import j
@@ -245,16 +245,16 @@
 ayList;%0A
-
 import j
@@ -358,17 +358,16 @@
 V3Dev%0A *
- 
 %0A * @aut
@@ -547,25 +547,24 @@
  a file.%0A%09 *
- 
 %0A%09 * @param 
@@ -1293,26 +1293,25 @@
 rn true;%0A%09%7D%0A
-%09
 %0A
+
 %09public stat
@@ -1453,26 +1453,25 @@
 ring());%0A%09%7D%0A
-%09
 %0A
+
 %09/**%0A%09 * Rea
@@ -2191,26 +2191,25 @@
  e);%0A%09%09%7D%0A%09%7D%0A
-%09
 %0A
+
 %09/**%0A%09 * Rea
@@ -2438,18 +2438,17 @@
 h));%0A%09%7D%0A
-%09
 %0A
+
 %09public 
@@ -2551,18 +2551,17 @@
 %0A%09%7D%0A
-%09
 %0A
+
 %09/**%0A%09 *
  %0A%09 
@@ -2556,17 +2556,16 @@
 %09/**%0A%09 *
- 
 %0A%09 * @pa
@@ -3436,182 +3436,79 @@
 ) %7B%0A
-        final File file = new File(path);%0A%09%09try (DataOutputStream out = new DataOutputStream(new FileOutputStream(file))) %7B%0A%09%09%09out.write(value);%0A%09%09%09out.flush();%0A%09%09%09out.close(
+%09%09try %7B%0A%09%09%09Files.write(Paths.get(path), value, StandardOpenOption.WRITE
 );%0A%09

Use Files.write() for LCD write