/**
 * isthere file notifier
 *
 * @since     1.0
 * @package   isthere
 * @copyright 2014
 * @license   See LICENSE
 */
package mcross1882.isthere;

import java.io.IOException;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Scanner;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import javax.mail.MessagingException;

/**
 * Main entry point for application
 *
 * @since  1.0
 * @access public
 * @author Matthew Cross <matthew@pmg.co>
 */
class IsThereApplication 
{
  protected static final String CONFIG_FILE = "config/main.config";
  
  protected static WatchService mWatcher = null;
  
  protected static Path mStartingDirectory;
  
  public static void main(String[] args)
  {
    HashMap<String, String> params = null;
    try {
      mWatcher = FileSystems.getDefault().newWatchService();
      // Resolve the base directory without the filename
      mStartingDirectory = Paths.get(args[0].substring(0, args[0].lastIndexOf("/")) + "/");
      
      params = loadConfiguration();
    } catch(Exception e) {
      e.printStackTrace();
      return;
    }
    
    System.out.println("Connecting to " + params.get("host") + " as " + params.get("user"));
    try {
      EmailService service = new EmailService(params.get("host"), 
        params.get("user"), 
        params.get("pass"), 
        Integer.parseInt(params.get("port")));

        watchFile(service, params.get("emailTo"), args[0].substring(args[0].lastIndexOf("/")+1));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  protected static HashMap<String, String> loadConfiguration()
    throws FileNotFoundException
  {
    HashMap<String, String> params = new HashMap<String, String>();
    Scanner reader = new Scanner(new File(CONFIG_FILE));
    
    while(reader.hasNext()) {
      setParameter(params, reader.nextLine());
    }
    reader.close();
    return params;
  }
  
  protected static void setParameter(HashMap<String, String> params, String line)
  {
    String[] fields = line.split(":");
    if (fields.length < 2) {
      return;
    }
    params.put(fields[0].trim(), fields[1].trim());
  }
  
  protected static void watchFile(EmailService service, String emailTo, String filename)
    throws MessagingException, IOException
  {
    boolean hasFile = true;
    File file = new File(filename);
    
    if (!file.exists() && !file.isDirectory()) {
      hasFile = false;
      sendFileMissingEmail(service, emailTo, filename);
    } else {
      hasFile = true;
      System.out.println("File is present");
    }
   
    WatchKey key = mStartingDirectory.register(mWatcher,
      StandardWatchEventKinds.ENTRY_CREATE,
      StandardWatchEventKinds.ENTRY_DELETE,
      StandardWatchEventKinds.ENTRY_MODIFY);
      
    while (!hasFile) {
      try {
        key = mWatcher.take();
      } catch (InterruptedException x) {
        return;
      }

      for (WatchEvent<?> event: key.pollEvents()) {
        WatchEvent.Kind kind = event.kind();

        if (kind == StandardWatchEventKinds.OVERFLOW) {
          continue;
        }

        WatchEvent<Path> ev = (WatchEvent<Path>)event;
        Path foundFile = ev.context();

        System.out.format("Comparing %s to %s", filename, foundFile);
        if (filename.equals(foundFile.toString())) {
          hasFile = true;
          sendFileArrivedEmail(service, emailTo, filename);
        }
      }

      if (!key.reset()) {
        break;
      }
    }
  }
  
  protected static void sendFileMissingEmail(EmailService service, String to, String filename)
    throws MessagingException
  {
    service.connect();
    service.sendEmail(new Email()
      .setTo(to)
      .setFrom("KoddiFileWatcher")
      .setSubject("File is missing [%s]".format(filename))
      .setMessage("The file " + filename + " is currently not available. When it arrives I will notify you again.")
    );
    service.close();
  }
  
  protected static void sendFileArrivedEmail(EmailService service, String to, String filename)
    throws MessagingException
  {
    service.connect();
    service.sendEmail(new Email()
      .setTo(to)
      .setFrom("KoddiFileWatcher")
      .setSubject("File has arrived " + filename)
      .setMessage("The file " + filename + " has arrived and is ready for processing.")
    );
    service.close();
  }
}

@@ -319,246 +319,8 @@
 ems;
-%0Aimport java.nio.file.Path;%0Aimport java.nio.file.Paths;%0Aimport java.nio.file.WatchEvent;%0Aimport java.nio.file.StandardWatchEventKinds;%0Aimport java.nio.file.WatchKey;%0Aimport java.nio.file.WatchService;%0Aimport javax.mail.MessagingException;
 %0A%0A/*
@@ -542,107 +542,8 @@
 %0A  %0A
-  protected static WatchService mWatcher = null;%0A  %0A  protected static Path mStartingDirectory;%0A  %0A
   pu
@@ -646,252 +646,264 @@
     
-mWatcher = FileSystems.getDefault().newWatchService();%0A      // Resolve the base directory without the filename%0A      mStartingDirectory = Paths.get(args%5B0%5D.substring(0, args%5B0%5D.lastIndexOf(%22/%22)) + %22/%22);%0A      %0A      params = loadConfiguration(
+params = loadConfiguration();%0A    %7D catch(Exception e) %7B%0A      e.printStackTrace();%0A      return;%0A    %7D%0A    %0A    FileWatcherService fileService = null;%0A    try %7B%0A      fileService = new FileWatcherService(args%5B0%5D, FileSystems.getDefault().newWatchService()
 );%0A 
@@ -904,32 +904,33 @@
 ());%0A    %7D catch
+ 
 (Exception e) %7B%0A
@@ -935,34 +935,88 @@
 %7B%0A      
-e.printStackTrace(
+System.err.println(String.format(%22Caught Exception: %25s%22, e.getMessage())
 );%0A     
@@ -1319,16 +1319,28 @@
         
+fileService.
 watchFil
@@ -2082,2187 +2082,6 @@
   %7D%0A
-  %0A  protected static void watchFile(EmailService service, String emailTo, String filename)%0A    throws MessagingException, IOException%0A  %7B%0A    boolean hasFile = true;%0A    File file = new File(filename);%0A    %0A    if (!file.exists() && !file.isDirectory()) %7B%0A      hasFile = false;%0A      sendFileMissingEmail(service, emailTo, filename);%0A    %7D else %7B%0A      hasFile = true;%0A      System.out.println(%22File is present%22);%0A    %7D%0A   %0A    WatchKey key = mStartingDirectory.register(mWatcher,%0A      StandardWatchEventKinds.ENTRY_CREATE,%0A      StandardWatchEventKinds.ENTRY_DELETE,%0A      StandardWatchEventKinds.ENTRY_MODIFY);%0A      %0A    while (!hasFile) %7B%0A      try %7B%0A        key = mWatcher.take();%0A      %7D catch (InterruptedException x) %7B%0A        return;%0A      %7D%0A%0A      for (WatchEvent%3C?%3E event: key.pollEvents()) %7B%0A        WatchEvent.Kind kind = event.kind();%0A%0A        if (kind == StandardWatchEventKinds.OVERFLOW) %7B%0A          continue;%0A        %7D%0A%0A        WatchEvent%3CPath%3E ev = (WatchEvent%3CPath%3E)event;%0A        Path foundFile = ev.context();%0A%0A        System.out.format(%22Comparing %25s to %25s%22, filename, foundFile);%0A        if (filename.equals(foundFile.toString())) %7B%0A          hasFile = true;%0A          sendFileArrivedEmail(service, emailTo, filename);%0A        %7D%0A      %7D%0A%0A      if (!key.reset()) %7B%0A        break;%0A      %7D%0A    %7D%0A  %7D%0A  %0A  protected static void sendFileMissingEmail(EmailService service, String to, String filename)%0A    throws MessagingException%0A  %7B%0A    service.connect();%0A    service.sendEmail(new Email()%0A      .setTo(to)%0A      .setFrom(%22KoddiFileWatcher%22)%0A      .setSubject(%22File is missing %5B%25s%5D%22.format(filename))%0A      .setMessage(%22The file %22 + filename + %22 is currently not available. When it arrives I will notify you again.%22)%0A    );%0A    service.close();%0A  %7D%0A  %0A  protected static void sendFileArrivedEmail(EmailService service, String to, String filename)%0A    throws MessagingException%0A  %7B%0A    service.connect();%0A    service.sendEmail(new Email()%0A      .setTo(to)%0A      .setFrom(%22KoddiFileWatcher%22)%0A      .setSubject(%22File has arrived %22 + filename)%0A      .setMessage(%22The file %22 + filename + %22 has arrived and is ready for processing.%22)%0A    );%0A    service.close();%0A  %7D%0A
 %7D%0A

Refactor IsThereApplication class to remove any FileWatcher methods and functionality.