package com.intuit.tank.storage;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * FileStorage that writes to the file system.
 * 
 * @author denisa
 *
 */
public class FileSystemFileStorage implements FileStorage, Serializable {

    private static final long serialVersionUID = 1L;
    private static final Logger LOG = LogManager.getLogger(FileSystemFileStorage.class);

    private String basePath;
    private boolean compress = true;

    /**
     * @param basePath
     */
    public FileSystemFileStorage(String basePath, boolean compress) {
        super();
        this.basePath = FilenameUtils.normalizeNoEndSeparator(basePath);
        this.compress = compress;
        File dir = new File(basePath);
        if (!dir.exists()) {
            LOG.info("Creating storage dir " + dir.getAbsolutePath());
        }
    }

    @Override
    public void storeFileData(FileData fileData, InputStream in) {
        File f = new File(FilenameUtils.normalize(basePath + "/" + fileData.getPath() + "/" + fileData.getFileName()));
        if (!f.getParentFile().exists()) {
            f.getParentFile().mkdirs();
        }
        OutputStream out = null;
        try {
            out = new FileOutputStream(f);
            if (compress) {
                out = new GZIPOutputStream(out);
            }
            IOUtils.copy(in, out);
        } catch (Exception e) {
            LOG.error("Error storing file: " + e, e);
            throw new RuntimeException(e);
        } finally {
            IOUtils.closeQuietly(out);
        }
    }

    @Override
    public InputStream readFileData(FileData fileData) {
        File f = new File(FilenameUtils.normalize(basePath + "/" + fileData.getPath() + "/" + fileData.getFileName()));
        InputStream ret = null;
        try {
            ret = new FileInputStream(f);
            if (compress) {
                ret = new GZIPInputStream(ret);
            }

        } catch (Exception e) {
            LOG.error("Error storing file: " + e, e);
            throw new RuntimeException(e);
        }
        return ret;
    }

    @Override
    public boolean exists(FileData fileData) {
        File f = new File(FilenameUtils.normalize(basePath + "/" + fileData.getPath() + "/" + fileData.getFileName()));
        return f.exists();
    }

    @Override
    public List<FileData> listFileData(String path) {
        File dir = new File(FilenameUtils.normalize(basePath + "/" + path));
        if (dir.exists()) {
            return Arrays.stream(dir.listFiles()).filter(File::isFile).map(f -> new FileData(path, f.getName())).collect(Collectors.toList());
        }
        return new ArrayList<FileData>();
    }

    @Override
    public boolean delete(FileData fileData) {
        File f = new File(FilenameUtils.normalize(basePath + "/" + fileData.getPath() + "/" + fileData.getFileName()));
        return f.delete();
    }

}

@@ -105,32 +105,60 @@
 leOutputStream;%0A
+import java.io.IOException;%0A
 import java.io.I
@@ -1415,16 +1415,19 @@
 tream in
+put
 ) %7B%0A    
@@ -1428,32 +1428,35 @@
 %7B%0A        File f
+ile
  = new File(File
@@ -1559,16 +1559,19 @@
   if (!f
+ile
 .getPare
@@ -1604,16 +1604,19 @@
        f
+ile
 .getPare
@@ -1652,16 +1652,21 @@
         
+try (
 OutputSt
@@ -1677,101 +1677,91 @@
  out
- = null;%0A        try %7B%0A            out = new FileOutputStream(f);%0A            if (compress) %7B
+put = compress ?%0A                new GZIPOutputStream(new FileOutputStream(file)) :
 %0A   
@@ -1777,54 +1777,38 @@
     
-out = new GZIPOutputStream(out);%0A            %7D
+new FileOutputStream(file) ) %7B
 %0A   
@@ -1835,11 +1835,17 @@
 y(in
-, o
+put, outp
 ut);
@@ -1854,32 +1854,34 @@
        %7D catch (
+IO
 Exception e) %7B%0A 
@@ -1980,67 +1980,8 @@
 e);%0A
-        %7D finally %7B%0A            IOUtils.closeQuietly(out);%0A
     
@@ -2070,32 +2070,35 @@
 %7B%0A        File f
+ile
  = new File(File
@@ -2199,31 +2199,43 @@
     
-InputStream ret = null;
+try %7B%0A            return compress ?
 %0A   
@@ -2231,38 +2231,33 @@
 press ?%0A        
-try %7B%0A
+ 
             ret 
@@ -2247,31 +2247,44 @@
             
- ret = 
+new GZIPInputStream(
 new FileInpu
@@ -2296,38 +2296,15 @@
 am(f
-);%0A            if (compress) %7B
+ile)) :
 %0A   
@@ -2320,22 +2320,20 @@
     
-ret =
+   
  new 
-GZIP
+File
 Inpu
@@ -2344,29 +2344,15 @@
 eam(
-ret
+file
 );%0A
-            %7D%0A%0A
     
@@ -2364,16 +2364,18 @@
  catch (
+IO
 Exceptio
@@ -2492,28 +2492,8 @@
   %7D%0A
-        return ret;%0A
     
@@ -2562,32 +2562,35 @@
 %7B%0A        File f
+ile
  = new File(File
@@ -2695,16 +2695,19 @@
 return f
+ile
 .exists(
@@ -3166,16 +3166,19 @@
   File f
+ile
  = new F
@@ -3291,16 +3291,19 @@
 return f
+ile
 .delete(
@@ -3315,7 +3315,5 @@
   %7D%0A
-%0A%7D%0A
+%7D

Update FileSystemFileStorage