package io.viper.core.server.file;


import com.thebuzzmedia.imgscalr.Scalr;
import io.viper.core.server.Util;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.imageio.ImageIO;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.json.JSONException;
import org.json.JSONObject;


// TODO: do this using chaining
public class ThumbnailFileContentInfoProvider implements FileContentInfoProvider
{
  private String _srcRootPath;
  private String _rootPath;
  String _metaFilePath;

  public static ThumbnailFileContentInfoProvider create(String srcRootPath)
  {
    return new ThumbnailFileContentInfoProvider(srcRootPath);
  }

  public ThumbnailFileContentInfoProvider(String srcRootPath)
  {
    _srcRootPath = srcRootPath.endsWith(File.separator) ? srcRootPath : srcRootPath + File.separator;
    _rootPath = srcRootPath + File.separator + ".thumb" + File.separatorChar;
    _metaFilePath = _rootPath + File.separatorChar + ".meta" + File.separatorChar;

    new File(_rootPath).mkdirs();
    new File(_metaFilePath).mkdirs();
  }

  @Override
  public FileContentInfo getFileContent(String path)
  {
    FileChannel fc = null;
    FileContentInfo result = null;

    // TODO: make a touch more secure - chroot to the rescue!
    try
    {
      final String fullPath = _rootPath + path + ".jpg";

      if (!fullPath.endsWith("/"))
      {
        File file;

        file = new File(fullPath);

        if (!file.exists())
        {
          // attempt to resize it
          File srcFile = new File(_srcRootPath + path);

          if (srcFile.exists())
          {
            BufferedImage image = ImageIO.read(srcFile);

            BufferedImage thumbnail = Scalr.resize(
                image,
                Scalr.Method.SPEED,
                Scalr.Mode.FIT_TO_WIDTH,
                150,
                100,
                Scalr.OP_ANTIALIAS);

            ImageIO.write(thumbnail, "jpg", file);
          }
        }

        if (file.exists())
        {
          Map<String, String> meta = new HashMap<String, String>();

          File metaFile = new File(_metaFilePath + path);
          if (metaFile.exists())
          {
            RandomAccessFile metaRaf = new RandomAccessFile(metaFile, "r");
            String rawJSON = metaRaf.readUTF();
            JSONObject jsonObject = new JSONObject(rawJSON);
            metaRaf.close();

            Iterator<String> keys = jsonObject.keys();
            while(keys.hasNext())
            {
              String key = keys.next();
              meta.put(key, jsonObject.getString(key));
            }
          }
          else
          {
            meta.put(HttpHeaders.Names.CONTENT_TYPE, Util.getContentType(file.getName()));
            meta.put(HttpHeaders.Names.CONTENT_LENGTH, Long.toString(file.length()));
          }

          result = FileContentInfo.create(file, meta);
        }
      }
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
    catch (JSONException e)
    {
      e.printStackTrace();
    }
    finally
    {
      if (result == null)
      {
        if (fc != null)
        {
          try
          {
            fc.close();
          }
          catch (IOException e)
          {
            e.printStackTrace();
          }
        }
      }
    }

    return result;
  }

  @Override
  public void dispose(FileContentInfo info)
  {
    if (info.fileChannel != null)
    {
      try
      {
        info.fileChannel.close();
        info.content.clear();
      }
      catch (IOException e)
      {
        e.printStackTrace();
      }
    }
  }
}

@@ -30,16 +30,61 @@
 file;%0A%0A%0A
+import com.thebuzzmedia.imgscalr.AsyncScalr;%0A
 import c
@@ -377,24 +377,108 @@
 a.util.Map;%0A
+import java.util.concurrent.ExecutionException;%0Aimport java.util.concurrent.Future;%0A
 import javax
@@ -1964,32 +1964,39 @@
 );%0A%0A            
+Future%3C
 BufferedImage th
@@ -1996,21 +1996,24 @@
 mage
- thumbnail = 
+%3E future = Async
 Scal
@@ -2142,10 +2142,10 @@
     
-15
+32
 0,%0A 
@@ -2163,10 +2163,10 @@
     
-10
+24
 0,%0A 
@@ -2198,24 +2198,127 @@
 NTIALIAS);%0A%0A
+            BufferedImage thumbnail = future.get();%0A            if (thumbnail != null)%0A            %7B%0A  
             
@@ -2356,16 +2356,30 @@
  file);%0A
+            %7D%0A
         
@@ -3466,24 +3466,170 @@
 ce();%0A    %7D%0A
+    catch (InterruptedException e)%0A    %7B%0A      e.printStackTrace();%0A    %7D%0A    catch (ExecutionException e)%0A    %7B%0A      e.printStackTrace();%0A    %7D%0A
     finally%0A

make img making async