/**
 * Flogman (Foto bLOG, Mail is All you Need)
 * Copyright (C) 2003 Junya Ishihara (http://flogman.sourceforge.net)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package net.sourceforge.flogman;
import java.util.*;
import java.io.*;
import java.text.*;
import org.apache.log4j.*;

public class Flogman {
  final static String version = "1.1";
  static Category cat = Category.getInstance(Flogman.class.getName());
  static Properties prop = new Properties();


  public static void sendNotificationMail() throws Exception {
    cat.info("Send a notification mail to " + prop.getProperty("sendmail_to"));
    SendMail.send(prop.getProperty("sendmail_smtp"), prop.getProperty("sendmail_from"), prop.getProperty("sendmail_to"), prop.getProperty("sendmail_subject"), prop.getProperty("sendmail_msgtxt"));
  }


  public static void updateNewTag() throws Exception {
    cat.info("Update New tags");
    UpdateNewTag unt = new UpdateNewTag(prop.getProperty("xml_file"), prop.getProperty("xml_charset"));
    if (unt.update()) {
      updateHTMLFile();
    } else {
      cat.info("Any New tag was not updated.");
    }
  }


  public static void deleteItem(String dirname) throws Exception {
    cat.info("Delete item " + dirname);
    ModifyHtml modifyHtml = new ModifyHtml(prop.getProperty("xml_file"), prop.getProperty("xml_charset"));

    if (modifyHtml.delete(dirname)) {
      updateHTMLFile();
    } else {
      cat.info("Any item was not deleted.");
    }
  }


  public static void uploadNewImages(String dirname, String subject, String filename) throws Exception {
    cat.info("Update xml file. Dirname: " + dirname + ", Description: " + subject + ", Filename: " + filename + ", Filetype: " + MyUtility.getFileType(filename));
    MakeHtml mhtml = new MakeHtml (prop.getProperty("xml_file"), prop.getProperty("xml_charset"));
    mhtml.makeHtml(dirname, subject, filename, MyUtility.getFileType(filename));
    // Upload files
    cat.info("Upload files. Dirname: " + dirname + ", Filename: " + filename);
    UploadFiles uf = new UploadFiles(prop.getProperty("ftp_server"), prop.getProperty("ftp_user"), prop.getProperty("ftp_pwd"));
    uf.uploadFiles(prop.getProperty("ftp_startdir"), dirname, filename);
    cat.info("Upload Done. Dirname: " + dirname + ", Filename: " + filename);
  }


  // Convert xml file to html file and then upload the html file.
  public static void updateHTMLFile() throws Exception {
    SimpleTransform.transform(prop.getProperty("xsl_file"), prop.getProperty("xml_file"), prop.getProperty("html_file"));

    cat.info("Upload files. Filename: " + prop.getProperty("html_file"));
    UploadFiles uf = new UploadFiles(prop.getProperty("ftp_server"), prop.getProperty("ftp_user"), prop.getProperty("ftp_pwd"));
    uf.uploadFiles(prop.getProperty("ftp_startdir"), prop.getProperty("html_file"));
    cat.info("Upload Done. Filename: " + prop.getProperty("html_file"));
  }


  // Delete downloaded file
  public static void deleteDownloadedFile(String filename) throws Exception {
    File temp_file = new File(filename);
    temp_file.delete();
    cat.info("Delete downloaded file: " + filename);
  }


  public static void main (String args[]) throws Exception {
    try {

    cat.info("Flogman (Foto Blog, Mail is All you Need) Ver. " + version);
    cat.info("Copyright (C) 2003 Junya Ishihara (http://flogman.sourceforge.net)");
    cat.info("");
    
    prop.load(new FileInputStream("Flogman.properties"));
    new TestLogging().init();

    cat.info("***Starting Program***");
    while (true) {
      GetMessage gm = new GetMessage(prop.getProperty("pop3_server"), prop.getProperty("pop3_user"), prop.getProperty("pop3_pwd"));
      String[] subject = gm.getSubjectArray();
      String[] filename = gm.getFilenameArray();
      String[] from = gm.getFromArray();

      if (gm.getNumberOfMessages() > 0) {
        for (int i=0, n=gm.getNumberOfMessages(); i<n; i++) {
          cat.info("Processing email No. " + (i + 1) +".");

          // Retrieve Email
          cat.info("Retrieving email. Subject is " + subject[i] + ", filename is " + filename[i]);
          cat.info("From: " + from[i]);

          
          //   If option restrict_sender=true, check whether the from address
          //   is equal to the value of option from_mailaddress. 

          if (prop.getProperty("restrict_sender").equals("true")) {

            // Parse From field
            String mailAddress;
            if (prop.getProperty("parse_from_field").equals("true")) {
              FromParser fp = new FromParser(from[i], "<>");
	      mailAddress = fp.getMailaddress();
              cat.info("From field is parsed. Mail Address is " + mailAddress);
            } else {
	      mailAddress = from[i];
              cat.info("From field is not parsed. Mail Address is " + mailAddress);
            }

            boolean unknownSender = true;
            StringTokenizer st = new StringTokenizer(prop.getProperty("from_mailaddress"), ",;: |");
            while (st.hasMoreTokens()) {
              if (mailAddress.toLowerCase().equals(st.nextToken().toLowerCase())) {
                cat.info(mailAddress + " is authorized sendor.");
                unknownSender = false;
                break;
              }
            }
            if (unknownSender == true) {
              cat.info("Unknown sendor. Skip the rest action.");
              continue;
            }
          }

          // Parse subject
          SubjectParser sp = new SubjectParser(subject[i], ",");
          cat.info("Subject parsed. FirstPart: " + sp.getFirstPart() + ", SecondPart:" + sp.getSecondPart());


          // If subject:"sendmail", send a notification mail
          if (sp.getFirstPart().toLowerCase().equals("sendmail")) {
            sendNotificationMail();


          // If subject:"update", update new tags
          } else if (sp.getFirstPart().toLowerCase().equals("update")) {
            updateNewTag();


          // If subject:"delete,YYYYMMDDHHMM(_N)", delete an item
          } else if (sp.getFirstPart().toLowerCase().equals("delete")) {
            deleteItem(sp.getSecondPart());


          // If subject:"text", upload the attachment to FTP site
          } else if ((filename[i] != null) && !(MyUtility.getFileType(filename[i]).equals("error"))) {

            // Create YYYYMMDDHHMM_N string for dir name
            Date dNow = new Date();
            String dirname;
            SimpleDateFormat formatter = new SimpleDateFormat ("yyyyMMddHHmm");
            if (gm.getNumberOfMessages() > 1) {
              dirname = formatter.format(dNow) + "_" + i;
            } else {
              dirname = formatter.format(dNow);
            }

            uploadNewImages(dirname, subject[i], filename[i]);
            updateHTMLFile();
            if (prop.getProperty("delete_downloaded_file","true").equals("true")) {
              deleteDownloadedFile(Flogman.prop.getProperty("upload_file_location") + "/" + filename[i]);
            } else {
              new File(Flogman.prop.getProperty("upload_file_location") + "/" + dirname).mkdir();
              File source = new File(Flogman.prop.getProperty("upload_file_location") + "/" + filename[i]);
              File dest = new File(Flogman.prop.getProperty("upload_file_location") + "/" + dirname + "/" + filename[i]);
              if (source.renameTo(dest)) cat.info("File is moved successfully. From: " + source + " to: " + dest);
            }
          }
        }
      }

      Thread.sleep(Integer.parseInt(prop.getProperty("getmessage_interval"))*60*1000);
    }

    } catch( Exception e ) {
      e.printStackTrace();
      cat.error(e);
    }
  }
}
