package com.flightstats.filesystem;

import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import lombok.SneakyThrows;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

import static java.util.stream.Collectors.toList;

public class LocalFileSystem implements FileSystem {

    @Override
    @SneakyThrows
    public OutputStream outputStream(Path fileName) {
        fileName.toFile().getParentFile().mkdirs();
        return new FileOutputStream(fileName.toFile());
    }

    @Override
    @SneakyThrows
    public InputStream inputStream(Path fileName) {
        return new FileInputStream(fileName.toFile());
    }

    @Override
    @SneakyThrows
    public String readContents(Path fileName) {
        return Joiner.on('\n').join(Files.readAllLines(fileName, Charsets.UTF_8));
    }

    @Override
    public boolean exists(Path fileName) {
        return fileName.toFile().exists();
    }

    @Override
    @SneakyThrows
    public void saveContent(String content, Path fileName) {
        fileName.toFile().getParentFile().mkdirs();
        Files.write(fileName, content.getBytes(Charsets.UTF_8));
    }

    @Override
    @SneakyThrows
    public List<Path> listFiles(Path directory) {
        return Files.list(directory).collect(toList());
    }

    @Override
    @SneakyThrows
    public void move(Path file, Path destinationDirectory) {
        Files.move(file, destinationDirectory.resolve(makeFileName(file)));
    }

    private String makeFileName(Path file) {
        return Joiner.on("/").join(file.iterator());
    }
}

@@ -140,72 +140,82 @@
 ws;%0A
-%0A
 import 
-java.io.FileInputStream;%0Aimport java.io.FileOutputStream
+org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0Aimport java.io.*
 ;%0Aim
@@ -228,22 +228,22 @@
 ava.
+n
 io.
-InputStream
+file.Files
 ;%0Aim
@@ -256,23 +256,21 @@
 ava.
+n
 io.
-OutputStream
+file.Path
 ;%0Aim
@@ -275,37 +275,39 @@
 import java.
-nio.file.File
+util.Collection
 s;%0Aimport ja
@@ -305,37 +305,33 @@
 import java.
-nio.file.Path
+util.List
 ;%0Aimport jav
@@ -337,20 +337,29 @@
 va.util.
-Li
 st
+ream.Stream
 ;%0A%0Aimpor
@@ -456,16 +456,105 @@
 System %7B
+%0A    private final static Logger logger = LoggerFactory.getLogger(LocalFileSystem.class);
 %0A%0A    @O
@@ -1402,34 +1402,16 @@
 verride%0A
-    @SneakyThrows%0A
     publ
@@ -1464,55 +1464,978 @@
     
-return Files.list(directory).collect(toList());
+//all this stuff is to make this method work like S3 does when you give it a prefix to search for.%0A        Path parent = directory.getParent();%0A        String prefix = directory.getFileName().toString();%0A%0A        try %7B%0A            Stream%3CPath%3E directories = Files.find(parent, 1, (path, attributes) -%3E path.getFileName().toString().startsWith(prefix));%0A            Stream%3CPath%3E files = directories.flatMap(d -%3E %7B%0A                try %7B%0A                    return Files.find(d, 100, (path, basicFileAttributes) -%3E basicFileAttributes.isRegularFile());%0A                %7D catch (IOException e) %7B%0A                    logger.warn(%22Error listing directory: %22 + directory, e);%0A                    return Collections.%3CPath%3EemptyList().stream();%0A                %7D%0A            %7D);%0A            return files.collect(toList());%0A        %7D catch (IOException e) %7B%0A            logger.warn(%22Error listing directory: %22 + directory, e);%0A            return Collections.emptyList();%0A        %7D
 %0A   
@@ -2718,10 +2718,11 @@
 ;%0A    %7D%0A
+%0A
 %7D%0A

make the listFiles method return files in sub-directories. This is to facilitate usage like it was S3.