package water.api;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import water.*;
import water.util.*;
import water.util.Log.LogStr;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class LogView extends Request {
  @Override protected Response serve() {
    String s = water.util.Log.getLogPathFileName();
    JsonObject result = new JsonObject();
    File f = new File (s);
    String contents = Utils.readFile(f);
    if (contents == null) {
      contents = "Not yet initialized, please refresh...";
    }
    result.addProperty("log", "<pre>" + contents + "</pre>");

    Response response = Response.done(result);
    response.addHeader("<a class='btn btn-primary' href='LogDownload.html'>Download all logs</a>");
    return response;
  }

  @Override protected boolean log() {
    return false;
  }

  static class LogDownload extends Request {

    @Override public water.NanoHTTPD.Response serve(NanoHTTPD server, Properties args, RequestType type) {
      // collect nodes' logs
      LogCollectorTask collector = new LogCollectorTask();
      collector.invokeOnAllNodes();

      // FIXME put here zip for each file.
      String outputFile = getOutputLogName();
      byte[] result = null;
      try {
        result = zipLogs(collector._result);
      } catch (IOException e) {
        // put the exception into output log
        result = e.toString().getBytes();
      }
      NanoHTTPD.Response res = server.new Response(NanoHTTPD.HTTP_OK,NanoHTTPD.MIME_DEFAULT_BINARY, new ByteArrayInputStream(result));
      res.addHeader("Content-Length", Long.toString(result.length));
      res.addHeader("Content-Disposition", "attachment; filename="+outputFile);
      return res;
    }

    @Override protected Response serve() {
      throw new RuntimeException("Get should not be called from this context");
    }

    private String getOutputLogName() {
      String pattern = "yyMMdd-hhmmss";
      SimpleDateFormat formatter = new SimpleDateFormat(pattern);
      String now = formatter.format(new Date());

      return "h2o-" + now + ".zip";
    }

    private byte[] zipLogs(byte[][] results) throws IOException {
      int l = 0;
      assert H2O.CLOUD._memary.length == results.length : "Unexpected change in the cloud!";
      for (int i = 0; i<results.length;l+=results[i++].length);
      ByteArrayOutputStream baos = new ByteArrayOutputStream(l);
      ZipOutputStream zos = new ZipOutputStream(baos);
      try {
        for (int i =0; i<results.length; i++) {
          String filename = "node"+i+H2O.CLOUD._memary[i].toString().replace(':', '_').replace('/', '_') + ".zip";
          ZipEntry ze = new ZipEntry(filename);
          zos.putNextEntry(ze);
          zos.write(results[i]);
          zos.closeEntry();
        }
      } finally { zos.close(); }

      return baos.toByteArray();
    }
  }
}

@@ -1302,16 +1302,20 @@
 tputFile
+Stem
  = getOu
@@ -1321,20 +1321,20 @@
 utputLog
-Name
+Stem
 ();%0A    
@@ -1407,24 +1407,40 @@
 ctor._result
+, outputFileStem
 );%0A      %7D c
@@ -1838,16 +1838,29 @@
 tputFile
+Stem + %22.zip%22
 );%0A     
@@ -2040,20 +2040,20 @@
 utputLog
-Name
+Stem
 () %7B%0A   
@@ -2230,25 +2230,16 @@
 -%22 + now
- + %22.zip%22
 ;%0A    %7D%0A
@@ -2282,16 +2282,31 @@
  results
+, String topDir
 ) throws
@@ -2558,16 +2558,51 @@
 ream(l);
+%0A%0A      // Add top-level directory.
 %0A      Z
@@ -2659,99 +2659,347 @@
     
-try %7B%0A        for (int i =0; i%3Cresults.length; i++) %7B%0A          String filename = %22node%22+i+
+%7B%0A        ZipEntry zde = new ZipEntry (topDir + File.separator);%0A        zos.putNextEntry(zde);%0A      %7D%0A%0A      try %7B%0A        // Add zip directory from each cloud member.%0A        for (int i =0; i%3Cresults.length; i++) %7B%0A          String filename =%0A                  topDir + File.separator +%0A                  %22node%22 + i +%0A                  
 H2O.
@@ -3063,16 +3063,34 @@
 , '_') +
+%0A                 
  %22.zip%22;
@@ -3245,25 +3245,138 @@
   %7D%0A
-      %7D finally %7B
+%0A        // Close the top-level directory.%0A        zos.closeEntry();%0A      %7D finally %7B%0A        // Close the full zip file.%0A       
  zos
@@ -3384,16 +3384,22 @@
 close();
+%0A     
  %7D%0A%0A    

Put top level files in a directory.