package commons.cmd;
import java.io.File;
import basics.filesystem.file.FileUtl;
import basics.filesystem.scanner.FileEventListener;
import basics.filesystem.scanner.FileSystemScanner;
import basics.random.Generator;
import basics.unexpected.Failure;
import basics.unexpected.Problem;
import basics.utl.Empty;
import basics.utl.SysUtl;
import commons.application.Application;
import commons.application.core.Command;
import commons.utl.CtxUtl;
/**
 * scans a folder (non-recursive) for file of a given pattern, invokes an operation on every file,
 * resulting file goes in a separate folder.
 * @author ks
 */
public class folderprocess extends Command implements FileEventListener
{

private static final String MUSTHAVE  = "folder,do";
private static final String ARGS      = "folder:<start-folder>;do:<service-name>;[output:<output-folder>;ext:<new-file-extension>;pattern:<file-matching-pattern>;cleanout:true|false]";
private String              tmpFolder = "";
private boolean             moveFile  = false;
private int                 counter   = 0;
String                      cmd       = null;
String                      output    = "";

// Command command = null;
public void init ()
{
   counter = 0;
   moveFile = false;
   tmpFolder = "";
}

public void process () throws Problem
{
   FileSystemScanner fscan = new FileSystemScanner(this);
   output = ctx.getr("output", "");
   if (!Empty.is(output))
   {
      output = FileUtl.concat(CtxUtl.userHome(ctx), output);
      FileUtl.mkdir(output);
      //      if (context.get("cleanout", false)) FileUtl.delete(context.get("output", ""), context.get("pattern", "*.*"));
   }
   else
   {
      if (Empty.is(ctx.getr("ext", "")))
      {
         output = FileUtl.concat(CtxUtl.userHome(ctx), Generator.createAZ19(6));
         FileUtl.mkdir(output);
         moveFile = true;
      }
      //      else if (context.get("cleanout", false)) FileUtl.delete(context.get("output", ""), context.get("pattern", "*.*"));
   }
   cmd = ctx.getr("do", "");
   if (Empty.is(cmd))
      throw new Problem("Missing param 'do' must point to a service name.");
   String folder = FileUtl.concat(CtxUtl.userHome(ctx), ctx.getr("folder", "."));
   fscan.startScan(folder, false);
   if (!FileUtl.delete(tmpFolder))
      SysUtl.trace("Deleting tmp-folder '" + tmpFolder + "' - failed.");
   Application.ui().print("Transformed " + counter + " files in " + folder + ".");
}

public void signContract ()
{
   demand(MUSTHAVE, null);
}

public String description ()
{
   return implName() + " scans a folder for files, and invokes an operation on every file. " + ARGS;
}

public boolean acceptFile (File file)
{
   return true;
}

public void nextFile (File file)
{
   try
   {
      String input = FileUtl.slashify(file.getAbsolutePath());
      String fname = FileUtl.getName(input);
      String targetFile;
      if (moveFile)
      {
         targetFile = FileUtl.concat(output, fname);
      }
      else
      {
         if (Empty.is(ctx.getr("ext", "")))
         {
            targetFile = FileUtl.concat(output, fname);
         }
         else
         {
            if (Empty.is(output))
            {
               SysUtl.trace("---" + FileUtl.getFolder(input) + " + " + FileUtl.getNameOnly(input));
               targetFile = FileUtl.concat(FileUtl.getFolder(input), FileUtl.getNameOnly(input)) + "." + ctx.getr("ext", "");
            }
            else
               targetFile = FileUtl.concat(output, FileUtl.getNameOnly(input)) + "." + ctx.getr("ext", "");
         }
      }
      String tmp = "tmp_" + Generator.createAZ19(2);
      ctx.put("input", input);
      ctx.put("output", targetFile);
      SysUtl.trace("input:" + input);
      SysUtl.trace("output:" + targetFile);
      engine.call(cmd, ctx, null, null);
      if (moveFile && !FileUtl.renameFile(targetFile, input))
         throw new Failure("Can't move file '" + targetFile + "' to '" + input + "'");
      counter++;
      ctx.remove(tmp);
   }
   catch (Throwable t)
   {
      t.printStackTrace();
      ctx.addError("Invoked service '" + cmd + "' failed. " + t.getMessage());
      // throw new Failure("Invoked service '" + service.getSignature() + "'
      // failed. "
      // + t.getMessage());
   }
}
}
