package basics.filesystem.scanner;
import java.io.File;
import java.util.ArrayList;
import basics.filesystem.file.FileUtl;
import basics.unexpected.Failure;
import basics.utl.SUtl;
/**
 * This is an implementation of the NextContentEventProducer, that notifies listeners when content
 * has been read. This implementation reads files in folders and archives.
 * @author ks
 */
public class FileSystemFolderAndArchiveScanner implements FileEventListener, JarEventListener, NextContentEventProducer
{

public static final String                  CTXKEY_PATTERN   = "pattern";
public static final String                  CTXKEY_FOLDER    = "folder";
public static final String                  CTXKEY_RECURSIVE = "recursive";
private ArrayList<NextContentEventListener> listeners        = new ArrayList<NextContentEventListener>();

public void registerNextContentConsumer (NextContentEventListener l)
{
   if (!listeners.contains(l)) listeners.add(l);
}

public void stop ()
{}

//public void start (Context ctx)
//{
//   scan(ctx.getr(CTXKEY_FOLDER, ""), ctx.getr(CTXKEY_PATTERN, ""), ctx.getr(CTXKEY_RECURSIVE, false));
//}

public void scan (String folder, String pattern, boolean recursive)
{
   // OsUtl.trace(this.getClass().getSimpleName() + ":");
   // OsUtl.trace("pattern: " + pattern);
   // OsUtl.trace("folder: " + folder);
   // OsUtl.trace("recursive: " + recursive);
   FileSystemScanner scanner = new FileSystemScanner(this);
   scanner.setPattern(SUtl.split(pattern, ","));
   scanner.startScan(folder, recursive);
}

public void dispatch (String protocol, String container, String name, String content)
{
   for (NextContentEventListener l : listeners)
      l.nextContent(protocol, container, name, content);
}

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

// file in folder
public void nextFile (File file)
{
   String filename = file.getAbsolutePath();
   String filelower = filename.toLowerCase();
   String ext = FileUtl.getExtension(filelower);
   // spezialfall archiv: jar und zip
   if (ext.equalsIgnoreCase("jar") || ext.equalsIgnoreCase("zip"))
   {
      try
      {
         JarScanner js = new JarScanner(this);
         js.startScan(filename);
      }
      catch (Throwable e)
      {
         throw new Failure(e.getMessage());
      }
      return;
   }
   // HACK: read binaries with no encoding set, txt with utf-8
   if (",doc,pdf,".indexOf(ext) > -1) dispatch("file", "", file.getAbsolutePath(), FileUtl.readBytes(file, ""));
   else dispatch("file", "", file.getAbsolutePath(), FileUtl.readBytes(file, "utf-8"));
}

// file in jar
public void nextEntry (String jarname, String entryname, String rawtext)
{
   dispatch("archive", jarname, entryname, rawtext);
}
}
