/**
 * This offers the preview image (JPEG) for locally stored recordings (files) to the network
 */
package org.bucksch.zeipis.store;
import org.bucksch.httpserver.*;
import org.bucksch.zeipis.all.Util;
import org.bucksch.zeipis.core.CoreServer;
import java.io.File;

public class LocalPreviewImageProvider implements HTTPHandler
{
  public LocalPreviewImageProvider()
  {
    CoreServer.me.dispatchingServer().registerHandler(this, "recorded/preview/image/full/");
  }
  public void handle(HTTPRequest request)
    throws HTTPException
  {
    if ( ! myHaveMplayer) // shortcut to avoid uselessly trying hundreds of times to generate previews
      throw new HTTPException(500, "Can not generate preview");
    int recordingid;
    try {
      recordingid = Integer.valueOf(request.getURLRest());
    } catch (NumberFormatException e) {
      throw new HTTPException(400, request.getURLPrefix() + " must be followed by a numeric ID of the recording, not " + request.getURLRest());
    }
    StoredRecording recording;
    try {
      recording = new StoredRecording(recordingid);
    } catch (Exception e) {
      throw new HTTPException(404, "Could not find recording " + recordingid, e);
    }
    if (!recording.isLocal())
      throw new HTTPException(404, "Recording " + recordingid + " is not a file on " + Util.thisHostname());
    String filename = recording.absFilename();
    filename = filename.replace(".mpg", ""); // TODO more general?
    filename = filename + ".jpg";
    String descr = "image preview " + filename + " for recording id " + recordingid;
    
    // Generate preview, if necessary
    // TODO server should not need to have mplayer (X11 app) installed
    if ( ! new File(filename).exists())
    {
      Util.debug("Generating preview of " + recording.absFilename() + ", using mplayer");
      // mplayer -vo jpeg -ss <skip-seconds> -frames 1 <filename>
      String[] args = new String[3];
      args[0] = "mplayer";
      args[1] = "-vo";
      args[2] = "jpeg";
      args[1] = "-ss";
      args[1] = String.valueOf(kSkipSeconds);
      args[1] = "-frames";
      args[2] = "1";
      args[2] = recording.absFilename();
      try {
        ProcessBuilder pb = new ProcessBuilder(args);
        Process proc = pb.start();
        int exitValue = proc.waitFor();
        if (exitValue != 0)
          throw new Exception("mplayer returned exit value " + exitValue + " while generating preview for " + recording.absFilename());
      } catch (Exception e) {
        myHaveMplayer = false;
        throw new HTTPException(500, "Could not start mplayer to generate preview: " + e);
      }

      // mplayer writes to file 00000001.jpg (in working dir), and I don't know a way to change that, so rename the files
      try {
        File file000 = new File("00000001.jpg");
        // TODO works across file systems (working dir to storage dir)?
        boolean success = file000.renameTo(new File(filename));
        if ( ! success)
          throw new Exception("Moving the generated preview file to its final location failed (" +
                  file000.getAbsolutePath() + " to " + filename);
      } catch (Exception e) { throw new HTTPException(500, "Moving the generated preview file to its final location failed: " + e); }
    } // Preview generated (or not)

    new HTTPFileResponse().respond(request, filename, "image/jpeg", descr);
  }
  
  // Config
  protected static int kSkipSeconds = 600; // 10 minutes. Capture preview as still image at this position in the video file.
  protected static boolean myHaveMplayer = true;
}
