/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * http://aipostyle.com/
 * 
 * Copyright(C) 2011 avanza Co.,Ltd. All rights reserved.
 * http://www.avnz.co.jp/
 * 
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */

package com.aimluck.eip.webmail;

import java.util.ArrayList;
import java.util.List;

import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALNumberField;
import com.aimluck.eip.cayenne.om.portlet.EipMMailAccount;
import com.aimluck.eip.cayenne.om.portlet.EipTMailFolder;
import com.aimluck.eip.common.ALAbstractFormData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.fileupload.beans.FileuploadLiteBean;
import com.aimluck.eip.fileupload.util.FileuploadUtils;
import com.aimluck.eip.mail.ALFolder;
import com.aimluck.eip.mail.ALLocalMailMessage;
import com.aimluck.eip.mail.file.ALFileLocalFolder;
import com.aimluck.eip.mail.util.ALMailUtils;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.services.storage.ALStorageService;
import com.aimluck.eip.util.ALEipUtils;
import com.aimluck.eip.webmail.util.WebMailUtils;

/**
 * メールアップロードのフォームデータを管理するクラスです。 <BR>
 * 
 */
public class WebMailUploadFormData extends ALAbstractFormData {

  /** logger */
  private static final JetspeedLogger logger =
    JetspeedLogFactoryService.getLogger(WebMailUploadFormData.class.getName());

  /** ログインユーザーのID * */
  private int user_id;

  private String orgId;

  /** メールアカウント */
  private EipMMailAccount mailAccount;

  /** アップロードファイルリスト */
  private List<FileuploadLiteBean> fileuploadList = null;

  /** アカウントに紐付くフォルダリスト */
  // private List<EipTMailFolder> folderList;
  public List<ExtFolderInfo> folderList;

  /** アップロード一時フォルダ名 */
  private String folderName = null;

  /** 格納フォルダID */
  private ALNumberField folderId;

  /**
   * 初期処理
   * 
   * @param action
   *            アクションクラス
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @see com.aimluck.eip.common.ALAbstractFormData#init(com.aimluck.eip.modules.actions.common.ALAction,
   *      org.apache.turbine.util.RunData, org.apache.velocity.context.Context)
   * 
   */
  @Override
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

    int mailAccountId = 0;

    // 自ポートレットからのリクエストであれば、パラメータを展開しセッションに保存する。
    if (ALEipUtils.isMatch(rundata, context)) {
      // セッションからアカウントIDを取得する。
      mailAccountId =
        Integer.parseInt(ALEipUtils.getTemp(
          rundata,
          context,
          WebMailUtils.ACCOUNT_ID));
    }

    user_id = ALEipUtils.getUserId(rundata);

    orgId = Database.getDomainName();

    // メールアカウントを取得する
    mailAccount = ALMailUtils.getMailAccount(user_id, mailAccountId);
    if (mailAccount == null) {
      return;

    }
    // remove start 受入テスト障害 190
    // try {
    // // 格納フォルダ一覧取得
    // folderList = ALMailUtils.getEipTMailFolderAll(mailAccount);
    // // ルートフォルダは除く
    // for (int i = 0; i < folderList.size(); i++) {
    // if (folderList.get(i).getParentFolderId() == 0) {
    // folderList.remove(i);
    // }
    // }
    // } catch (Exception e) {
    // logger.error(
    // "メールアップロード初期表示に失敗しました" + ALEipUtils.getUserFullName(user_id),
    // e);
    // }
    // remove end 受入テスト障害 190

    folderName = rundata.getParameters().getString("folderName");

  }

  /**
   * 画面フィールド初期化
   * 
   * @see com.aimluck.eip.common.ALData#initField()
   */
  @Override
  public void initField() {

    // アップロードファイルリスト
    fileuploadList = new ArrayList<FileuploadLiteBean>();

    // 格納フォルダ
    folderId = new ALNumberField();
    folderId.setFieldName("格納フォルダ");

  }

  /**
   * バリデータ初期化
   * 
   * @see com.aimluck.eip.common.ALAbstractFormData#setValidator()
   */
  @Override
  protected void setValidator() {

    // 格納フォルダ必須項目
    folderId.setNotNull(true);
  }

  /**
   * バリデーション
   * 
   * @param msgList
   *            エラーメッセージリスト
   * @return TRUE 成功 FALSE 失敗
   * @see com.aimluck.eip.common.ALAbstractFormData#validate(java.util.ArrayList)
   */
  @Override
  protected boolean validate(List<String> msgList) {

    try {
      // メールアップロードリストが未指定
      if (fileuploadList == null || fileuploadList.size() == 0) {
        msgList.add("『メールファイル』を選択してください。");
      } else {
        int index = 0;
        String fileName = null;
        List<String> fileNameList = new ArrayList<String>();
        for (int i = 0; i < fileuploadList.size(); i++) {
          // アップロードファイルの拡張子が".eml"以外は不可
          fileName = fileuploadList.get(i).getFileName();
          index = fileName.lastIndexOf('.');
          if (!("eml".equals(fileName.substring(index + 1)))) {
            msgList.add("『 メールファイル 』はeml形式のみ選択可能です。 " + fileName);
          }
          // ファイル選択重複チェック
          if (fileNameList.contains(fileName)) {
            msgList.add("既に指定されているファイルです。 " + fileName);
          } else {
            fileNameList.add(fileName);
          }
        }
      }

      // 格納フォルダID
      folderId.validate(msgList);

      return (msgList.size() == 0);
    } catch (Exception e) {
      logger.error("メールアップロード 入力チェックに失敗しました"
        + ALEipUtils.getUserFullName(user_id), e);
      return false;
    }

  }

  /**
   * データベースから読み出します。 <BR>
   * 
   * @param action
   *            アクションクラス
   * @param rundata
   *            JetSpeedランデータ
   * @param msgList
   *            エラーメッセージリスト
   * @return TRUE 成功 FALSE 失敗
   */
  @Override
  protected boolean loadFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {

    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * データベースから削除します。 <BR>
   * 
   * @param action
   *            アクションクラス
   * @param rundata
   *            JetSpeedランデータ
   * @param msgList
   *            エラーメッセージリスト
   * @return TRUE 成功 FALSE 失敗
   */
  @Override
  protected boolean deleteFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {

    } catch (Throwable t) {
      Database.rollback();
      logger.error(t);
      return false;
    }
    return true;
  }

  /**
   * メールファイルをアップロードしてデータベースに格納します。 <BR>
   * 
   * @param action
   *            アクションクラス
   * @param rundata
   *            JetSpeedランデータ
   * @param msgList
   *            エラーメッセージリスト
   * @return TRUE 成功 FALSE 失敗
   */
  @Override
  protected boolean insertFormData(RunData rundata, Context context,
      List<String> msgList) {

    String[] attachmentFilepaths = null;
    try {
      FileuploadLiteBean filebean = null;
      if (fileuploadList != null && fileuploadList.size() > 0) {
        int size = fileuploadList.size();
        attachmentFilepaths = new String[size];

        ALLocalMailMessage msg = null;

        // フォルダIDよりフォルダ情報取得
        EipTMailFolder folder =
          ALMailUtils.getEipTMailFolder(mailAccount, folderId.toString());

        // フォルダ種別よりメール種別を判別
        int type_mail =
          (folder.getFolderKind().equals(ALMailUtils.FOLDER_KIND_RECEIVE))
            ? ALFolder.TYPE_RECEIVE
            : ALFolder.TYPE_SEND;

        ALFileLocalFolder fileLocalfolder =
          new ALFileLocalFolder(type_mail, orgId, user_id, mailAccount
            .getAccountId());

        // アップロードされたファイルの数だけ繰り返す
        for (int i = 0; i < size; i++) {
          filebean = fileuploadList.get(i);
          // アップロードされたメールファイルのフルパスを取得
          attachmentFilepaths[i] =
            ALStorageService.getDocumentPath(
              FileuploadUtils.FOLDER_TMP_FOR_ATTACHMENT_FILES,
              user_id + ALStorageService.separator() + folderName)
              + ALStorageService.separator()
              + filebean.getFileId();

          // アップロードされたメールファイルの内容を取得
          msg = ALMailUtils.readMail(attachmentFilepaths[i]);

          // add start 2012.1.11 Content-Transfer-Encoding:が正しくない場合の対応
          String[] str_list_encoding =
            msg.getHeader(ALLocalMailMessage.CONTENT_TRANSFER_ENCORDING);
          if (!(null == str_list_encoding || "".equals(str_list_encoding))) {
            String str_encoding = str_list_encoding[0];
            if ("sevenbit".equals(str_encoding)) {
              msg.setHeader(
                ALLocalMailMessage.CONTENT_TRANSFER_ENCORDING,
                "7bit");
            }
          }
          // add end

          // アップロードファイルをサーバー上のメールファイル、DBに登録
          fileLocalfolder.saveMailByFolder(msg, folderId.toString());

        }
        // 添付ファイル保存先のフォルダを削除
        ALStorageService.deleteTmpFolder(user_id, folderName);
      }

      return true;

    } catch (Throwable t) {
      Database.rollback();
      String msg =
        "メールアップロードに失敗しました。["
          + ALEipUtils.getBaseUser(user_id).getUserName()
          + "]";
      logger.error(msg, t);
      return false;
    }
  }

  /**
   * 画面表示項目を設定します <BR>
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @param msgList
   *            エラーメッセージリスト
   * @return true:処理成功 false:処理失敗
   */
  @Override
  protected boolean setFormData(RunData rundata, Context context,
      List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {

    boolean res = super.setFormData(rundata, context, msgList);

    try {
      fileuploadList = FileuploadUtils.getFileuploadList(rundata);

      // add start 受入テスト障害 190
      if (ALEipConstants.MODE_NEW_FORM.equals(getMode())) {
        loadMailFolderList(rundata, context);
      }
      // add end
    } catch (Exception ex) {
      logger.error("Exception", ex);
    }

    return res;
  }

  /**
   * データベースを更新します。 <BR>
   * 
   * @param action
   *            アクションクラス
   * @param rundata
   *            JetSpeedランデータ
   * @param msgList
   *            エラーメッセージリスト
   * @return TRUE 成功 FALSE 失敗
   */
  @Override
  protected boolean updateFormData(RunData rundata, Context context,
      List<String> msgList) {
    try {

    } catch (Throwable t) {
      Database.rollback();
      logger.error(t);
      return false;
    }
    return true;
  }

  /**
   * フォルダ一覧を取得する． <BR>
   * 
   * @return
   */
  // public List<EipTMailFolder> getFolderList() {
  public List<ExtFolderInfo> getMailFolderList() {
    return folderList;
  }

  /**
   * @return
   */
  public List<FileuploadLiteBean> getAttachmentFileNameList() {
    return fileuploadList;
  }

  /**
   * @return folderName
   */
  public String getFolderName() {
    return folderName;
  }

  /**
   * 格納フォルダIDを取得する． <BR>
   * 
   * @return
   */
  public ALNumberField getFolderId() {
    return folderId;
  }

  // add start 受入テスト障害 190
  /**
   * 
   * ログインユーザーのメールフォルダ一覧表示処理。
   * 
   * @param rundata
   * @param context
   */
  public void loadMailFolderList(RunData rundata, Context context) {
    if (mailAccount == null) {
      return;
    }
    try {
      folderList = new ArrayList<ExtFolderInfo>();

      List<ExtFolderInfo> tmp =
        WebMailUtils.getFolderList(
          WebMailUtils.ROOT_PARENT_FODLER_ID,
          mailAccount.getAccountId(),
          WebMailConsts.RECEIVE_FOLDER);

      folderList.addAll(tmp);

      tmp =
        WebMailUtils.getFolderList(
          WebMailUtils.ROOT_PARENT_FODLER_ID,
          mailAccount.getAccountId(),
          WebMailConsts.SEND_FOLDER);

      folderList.addAll(tmp);

    } catch (Exception ex) {
      logger.error("Exception", ex);
    }
  }
  // add end 受入テスト障害 190
}
