/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2011 Aimluck,Inc.
 * http://www.aipo.com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package aipo.batch.exec;

import java.io.File;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.access.Transaction;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.resources.JetspeedResources;

import aipo.batch.userinfo.GroupsendImporter;
import aipo.batch.userinfo.MailAccountImporter;
import aipo.batch.userinfo.PositionImporter;
import aipo.batch.userinfo.PostImporter;
import aipo.batch.userinfo.RoleImporter;
import aipo.batch.userinfo.UserGroupsendImporter;
import aipo.batch.userinfo.UserImporter;
import aipo.batch.userinfo.UserRoleImporter;
import aipo.batch.utils.BatchUtils;

import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.orm.Database;

/**
 * <HR>
 * ユーザー情報移行バッチ実行クラス
 * <p>
 * 
 * ユーザー情報移行バッチ処理を実行します。
 * <P>
 * <HR>
 * <P>
 * 
 */
public class UserInfoImportBatchExecuter {

  /** ロガー */
  private static final JetspeedLogger logger =
    JetspeedLogFactoryService.getLogger(UserInfoImportBatchExecuter.class
      .getName());

  /** プロパティファイル */
  private static final String PROPERTY_FILE =
    JetspeedResources.getString("aipo.conf", "")
      + File.separator
      + "Batch.properties";

  /** 部署ファイル名 */
  private static final String POST_FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.post.file.name");

  /** 役職ファイル名 */
  private static final String POSITION_FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.position.file.name");

  /** 役割ファイル名 */
  private static final String ROLE_FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.role.file.name");

  /** ユーザーファイル名 */
  private static final String USER_FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.user.file.name");

  /** メールアカウントファイル名 */
  private static final String MAIL_ACCOUNT_FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.mailaccount.file.name");

  /** グループ送信ファイル名 */
  private static final String GROUPSEND_FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.groupsend.file.name");

  /** グループ送信割当ファイル名 */
  private static final String GROUPSEND_USER__FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.groupsenduser.file.name");

  /** 役割割当ファイル名 */
  private static final String USER_ROLE_FILE_NAME =
    (String) BatchUtils.getProperties(PROPERTY_FILE).get(
      "import.userrole.file.name");

  /**
   * ユーザー情報移行バッチ実行
   * <p>
   * 組織情報、役職情報、役割情報、ユーザー情報、メールアカウント割当、グループ送信、グループ送信割当、役割割当の順に<br>
   * インポート処理を実行する。<br>
   */
  public void executeUserInfoImportBatch() {
    boolean result = false;

    logger.info("ユーザー情報移行処理開始");

    // 標準のトランザクション（オートコミット）
    Transaction baseTx = Transaction.getThreadTransaction();

    // 自己管理トランザクション
    Transaction tx =
      Transaction.internalTransaction(DataContext
        .getThreadDataContext()
        .getParentDataDomain()
        .getTransactionDelegate());

    DataContext dataContext = DataContext.getThreadDataContext();
    // 標準のトランザクションを自己管理トランザクションに置き換えます。
    Transaction.bindThreadTransaction(tx);

    try {
      // トランザクションモードを切替するため、一旦コミット
      // Database.commit();
      Database.sql(
        TurbineUser.class,
        "SET TRANSACTION ISOLATION LEVEL READ COMMITTED;").execute();
      // Database
      // .sql(
      // TurbineUser.class,
      // "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ
      // COMMITTED;")
      // .execute();
      // tx =
      // Transaction.externalTransaction(DataContext
      // .getThreadDataContext()
      // .getParentDataDomain()
      // .getTransactionDelegate());
      //
      // Transaction.bindThreadTransaction(tx);
      logger.info("トランザクションモードを切替しました。");

      // トランザクション開始
      // tx.begin();

      // 組織情報更新
      PostImporter post = new PostImporter();
      result = post.importPost(dataContext);
      if (!result) {
        throw new Exception();
      }
      PositionImporter position = new PositionImporter();
      // 役職情報更新
      result = position.importPosition(dataContext);
      if (!result) {
        throw new Exception();
      }

      // 役割情報更新
      RoleImporter role = new RoleImporter();
      result = role.importRole(dataContext);
      if (!result) {
        throw new Exception();
      }

      // ユーザー情報更新
      UserImporter user = new UserImporter();
      result = user.importUserInfo(dataContext);
      if (!result) {
        throw new Exception();
      }

      // メールアカウント割当更新
      MailAccountImporter mailAccount = new MailAccountImporter();
      result = mailAccount.importMailAccount(dataContext);
      if (!result) {
        throw new Exception();
      }

      // グループ送信情報更新
      GroupsendImporter groupsend = new GroupsendImporter();
      result = groupsend.importGroupsend(dataContext);
      if (!result) {
        throw new Exception();
      }

      // グループ送信割当情報更新
      UserGroupsendImporter userGroupsend = new UserGroupsendImporter();
      result = userGroupsend.importGroupSendUser(dataContext);
      if (!result) {
        throw new Exception();
      }

      // 役割割当更新
      UserRoleImporter userRole = new UserRoleImporter();
      result = userRole.importUserRole(dataContext);
      if (!result) {
        throw new Exception();
      }

      // 登録処理を確定
      Database.commit();

      // 正常終了の場合、ファイルを削除する。
      File postFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + POST_FILE_NAME);
      if (postFile.exists()) {
        if (!postFile.delete()) {
          logger.warn("組織情報ファイル削除に失敗しました。ファイルパス：["
            + postFile.getAbsolutePath()
            + "]");
        }
      }

      // 正常終了の場合、ファイルを削除する。
      File positionFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + POSITION_FILE_NAME);
      if (positionFile.exists()) {
        if (!positionFile.delete()) {
          logger.warn("役職情報ファイル削除に失敗しました。ファイルパス：["
            + positionFile.getAbsolutePath()
            + "]");
        }
      }

      File roleFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + ROLE_FILE_NAME);
      if (roleFile.exists()) {
        if (!roleFile.delete()) {
          logger.warn("役割情報ファイル削除に失敗しました。ファイルパス：["
            + roleFile.getAbsolutePath()
            + "]");
        }
      }

      File userFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + USER_FILE_NAME);
      if (userFile.exists()) {
        if (!userFile.delete()) {
          logger.warn("ユーザー情報ファイル削除に失敗しました。ファイルパス：["
            + userFile.getAbsolutePath()
            + "]");
        }
      }

      File mailAccountFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + MAIL_ACCOUNT_FILE_NAME);
      if (mailAccountFile.exists()) {
        if (!mailAccountFile.delete()) {
          logger.warn("メールアカウント割当ファイル削除に失敗しました。ファイルパス：["
            + mailAccountFile.getAbsolutePath()
            + "]");
        }
      }

      File groupsendFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + GROUPSEND_FILE_NAME);
      if (groupsendFile.exists()) {
        if (!groupsendFile.delete()) {
          logger.warn("グループ送信情報ファイル削除に失敗しました。ファイルパス：["
            + groupsendFile.getAbsolutePath()
            + "]");
        }
      }

      File userGroupsendFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + GROUPSEND_USER__FILE_NAME);
      if (userGroupsendFile.exists()) {
        if (!userGroupsendFile.delete()) {
          logger.warn("グループ送信割当ファイル削除に失敗しました。ファイルパス：["
            + userGroupsendFile.getAbsolutePath()
            + "]");
        }
      }

      File userRoleFile =
        new File(BatchUtils.IMPORT_CSV_FILE_PATH
          + File.separator
          + USER_ROLE_FILE_NAME);
      if (userRoleFile.exists()) {
        if (!userRoleFile.delete()) {
          logger.warn("役割割当ファイル削除に失敗しました。ファイルパス：["
            + userRoleFile.getAbsolutePath()
            + "]");
        }
      }

      logger.info("ユーザー情報移行処理終了");

    } catch (Exception e) {
      // 登録処理をキャンセル
      Database.tearDown();
      logger.error("ユーザー情報移行処理でエラーが発生しました。", e);
    } finally {
      // 自己管理トランザクションを標準のトランザクションに戻します。
      Transaction.bindThreadTransaction(baseTx);
    }
  }
}
