/*
このファイルの中身は、NTT オープンソースライセンス　バージョン 1.0（「本
契約」という）の適用を受けます。
本契約を遵守しない限り、このファイルを使用してはなりません。
本契約のコピーは、次のＵＲＬから入手できます。
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

本契約に基づき頒布されるソフトウェアは、現状のまま、明示又は黙示のあらゆ
る種類の保証なしで、頒布されます。本契約に基づく権利及び制限を律する特定
の文言については、本契約を参照してください。

「オリジナルコード」は、 NTT Cyber Space Laboratories Code です。 
「オリジナルコード」の「初期開発者」は、日本電信電話株式会社です。  
日本電信電話株式会社により創作された部分は、Copyright (C) 2004 
日本電信電話株式会社 です。
全ての権利が留保されます。 
「コントリビュータ」：_____________________________________ 


The contents of this file are subject to the NTT Opensource License
Version 1.0 (the License); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

Software distributed under the License is distributed on an AS IS
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is NTT Cyber Space Laboratories Code .

The Initial Developer of the Original Code is NIPPON TELEGRAPH AND 
TELEPHONE CORPORATION.
Portions created by the NIPPON TELEGRAPH AND TELEPHONE CORPORATION 
are Copyright (C) 2004 NIPPON TELEGRAPH AND TELEPHONE CORPORATION. 
All Rights Reserved.

Contributor(s) ______________________________________.
*/

//
// 個別ログ進捗状況一覧CSV出力用・アクションクラス。<br>
//
//
//  変更履歴
//  2004/01/08 新規作成  S.Takahashi
//
package jp.co.ntt.lms.xms.logsumup;

import java.util.Date;
import java.text.DecimalFormat;

import javax.servlet.http.HttpServletRequest;
import jp.co.ntt.lms.Common.RDF.RDFNode;
import jp.co.ntt.lms.xmo.util.ChangeEncode;
import jp.co.ntt.lms.xmo.util.XMODate;
import jp.co.ntt.lms.xms.framework.Constant;
import jp.co.ntt.lms.xms.framework.XmsException;
import jp.co.ntt.lms.xms.framework.XmsInnerException;
import jp.co.ntt.lms.xms.framework.XmsRequest;
import jp.co.ntt.lms.xms.framework.XmsResponse;
import jp.co.ntt.lms.xms.framework.XmsScreenBean;
import jp.co.ntt.lms.xms.framework.base.AbstractRmiAction;
import jp.co.ntt.lms.xms.framework.base.ActionResultBean;
import jp.co.ntt.lms.xms.framework.base.Logic;

/**
 * ログ集計グループ比較結果フレーム出力用アクション・クラス。<br>
 *
 * @author S.Takahashi
 */
public class IndividualLogGroupProgressAction extends AbstractRmiAction {

    /**
     * リスエストされたLOID
     */
    private String LOID;
    /**
     * リスエストされたグループID
     */
    private String GroupID;
    /**
     * リスエストされたLoType
     */
    private String LOType;
    /**
     * リスエストされたUID
     */
    private String UID;
    /**
     * リスエストされたRDFNode
     */
    private RDFNode node;
    /**
     * リクエストされた配下フラグ
     */
    private String Reflex;

    /**
     * ロジッククラス配列を戻す。<br>
     * @param request リクエストオブジェクト。
     * @return IndividualLogGroupProgressLogicクラスオブジェクト１要素だけの配列。
     * @see IndividualLogGroupProgressLogic
     */
    protected Logic[] getLogics(XmsRequest request) throws XmsException {

        Logic[] logSumUps = null;
        logSumUps = new Logic[1];
        // Logicクラスの派生クラスを生成
        logSumUps[0] =
            new IndividualLogGroupProgressLogic(
                GroupID,
                LOID,
                LOType,
                Reflex,
                node);

        return logSumUps;

    }

    /**
     * リクエスト初期化処理。<br>
     * パラメータ名称&quot;userid&quot;、&quot;loid&quot;で送信された
     * リクエストパラメータをリスト化して、内部で保持する。
     *
     * @param xmsRequest   HTTPリスエスト
     * @param xmsResponse  HTTPレスポンス
     * @see jp.co.ntt.lms.xms.framework.base.AbstractRmiAction#initProsessRequest(XmsRequest)
     */
    public void initProcessRequest(
        XmsRequest xmsRequest,
        XmsResponse xmsResponse)
        throws XmsException {
        // スーパークラスのメソッドを呼び出し。
        super.initProcessRequest(xmsRequest, xmsResponse);

        HttpServletRequest request = null;

        request = xmsRequest.getRequest();

        // LoIDをパラメータより取得
        this.LOID = ChangeEncode.setHttpChar(request.getParameter("LoID"));
        // ユーザーIDをパラメータより取得
        this.GroupID = ChangeEncode.setHttpChar(request.getParameter("userId"));
        // LOTypeをパラメータより取得
        this.LOType = ChangeEncode.setHttpChar(request.getParameter("LoType"));
        // 基本LO名をパラメータより取得
        this.UID = ChangeEncode.setHttpChar(request.getParameter("UID"));
        // 基本外部LOIDをパラメータより取得
        this.Reflex = ChangeEncode.setHttpChar(request.getParameter("reflex"));
        // 教材構造を取得
        RDFNode rdfNode = (RDFNode)request.getSession().getAttribute(LOID);
        this.node = rdfNode.searchNode( UID );

        // パラメータチェック
        if (LOID.equals("")
            || GroupID.equals("")
            || LOType.equals("")
            || UID.equals("")
            || node == null) {
            throw new XmsInnerException("parameter is null.");
        }

    }

    /**
     * 検索結果をＣＳＶ文字列に変換する。<br>
     * このメソッドは渡されるbeanがActionResultBeanであり、
     * 内部にIndividualLogGroupProgressResultを保持していることを期待しています。
     *
     * @param bean アクション実行結果オブジェクト。
     * @return beanの中からIndividualLogGroupProgressResultを取得し、CSVに変換した文字列。
     * @see ActionResultBean
     * @see IndividualLogGroupProgressResult
     * @throws 渡されたbeanが不正などCSV変換に問題が発生した場合。
     */
    public String convertToCSV(XmsScreenBean bean) {

        // 戻り値
        String retVal = null;
        // 戻り値作成用バッファ
        StringBuffer buffer = null;
        // リザルトクラス
        ActionResultBean resultBean = null;
        // グループログ集計結果専用クラス
        IndividualLogGroupProgressResult logResult = null;
        LoLogCommon_inc cominc = new LoLogCommon_inc();
        DecimalFormat objFormat = new DecimalFormat( "#######0.0" );


        try {
            buffer = new StringBuffer();
            resultBean = (ActionResultBean) bean;
            // 先頭要素となっているロジック結果を取得
            logResult =
                (IndividualLogGroupProgressResult) resultBean.getFirstLogResult();

            // =================================================================
            // CSVレポート部
            // #レポート
            // 進捗状況(グループ指定)
            buffer.append(
                 IndividualLogGroupProgressConstant.STR_REPORT_o + "," );
            // ＬＯ
            buffer.append( IndividualLogGroupProgressConstant.STR_LO_o + ":");
            // LO名
            buffer.append( logResult.getLOName() );
            // セクション名
            buffer.append("/" + logResult.getSectionName() );
            // LO外部ID
			buffer.append("(" + logResult.getForeignLOID() + "),");
            // グループ
            buffer.append( IndividualLogGroupProgressConstant.STR_GROUP_o + ":");
            // グループ名
            buffer.append( logResult.getGroupName() );
            // グループ外部ID
            buffer.append("(" + logResult.getGroupForeignId() + "),");
            // 集計対象者数
            buffer.append( IndividualLogGroupProgressConstant.STR_CANDIDATE_TOTAL_COUNT_o + ":");
			// グループ直下の場合
			if ( Reflex.equals("") ) {
	            // 直下ユーザ数（取得レコード数が直下ユーザ数と一致する）
	            buffer.append(IndividualLogGroupProgressConstant.STR_DIRECTLY_UNDER_USER_o + logResult.size() + IndividualLogGroupProgressConstant.STR_PERSON_o );
			// グループ配下の場合
			} else {
				// 配下ユーザ数（取得レコード数が配下ユーザ数と一致する）
				buffer.append(IndividualLogGroupProgressConstant.STR_SUBORDINATE_USER_o + logResult.size() + IndividualLogGroupProgressConstant.STR_PERSON_o );
			}
            // 行区切り文字
            buffer.append(Constant.LINE_SEPARATOR);


            // =================================================================
            // CSV個別ヘッダ部
            // 学習者
            buffer.append( IndividualLogGroupProgressConstant.STR_STUDENT_o );
            buffer.append(",");
            // 学習者外部ID
            buffer.append( IndividualLogGroupProgressConstant.STR_FOREIGN_ID_o );
            buffer.append(",");
            // 所属グループ
            buffer.append( IndividualLogGroupProgressConstant.STR_GROUPS_o );
            buffer.append(",");
            // グループ外部ID
            buffer.append( IndividualLogGroupProgressConstant.STR_FOREIGN_ID_o );
            buffer.append(",");
            // 学習開始日時
            buffer.append( IndividualLogGroupProgressConstant.STR_DATE_START_o );
            buffer.append(",");
            // 最終アクセス日時
            buffer.append( IndividualLogGroupProgressConstant.STR_DATE_LAST_o );
            buffer.append(",");
            // アクセス回数
            buffer.append( IndividualLogGroupProgressConstant.STR_ACCESS_COUNT_o );
            buffer.append(",");
            // 累積滞在時間
            buffer.append( IndividualLogGroupProgressConstant.STR_TOTAL_LEARN_TIME_o );
            buffer.append(",");
            // 得点（最新）
            buffer.append( IndividualLogGroupProgressConstant.STR_NEWEST_SCORE_o );
            buffer.append(",");
            // 得点（最高）
            buffer.append( IndividualLogGroupProgressConstant.STR_HIGH_SCORE_o );
            buffer.append(",");
            // 完了率
            buffer.append( IndividualLogGroupProgressConstant.STR_COMPLETE_UNIT_o );
            buffer.append(",");
            // 合格率
            buffer.append( IndividualLogGroupProgressConstant.STR_PASS_UNIT_o );
            buffer.append(",");
            // アサイン
            buffer.append( IndividualLogGroupProgressConstant.STR_ASSIGN_o );
            // 行区切り文字
            buffer.append(Constant.LINE_SEPARATOR);


            // =================================================================
            // データ部
            // アクセス数集計
            long lngSumAccessCount = 0;
            // 累積滞在時間集計
            long lngSumResidanceTime = 0;
            // 得点（最新）集計
            float fltSumNewestScore = 0;
            // 得点（最高）集計
            float fltSumHighScore = 0;
            // 完了ユニット数集計
            long lngSumCompUnit = 0;
            // 合格ユニット数集計
            long lngSumPassUnit = 0;
            // 全ユーザのAU数
            long lngSumAllUnit = 0;
            // AICCCOREテーブルにデータがあるユーザ数
            long lngSumAiccUser = 0;
            // 得点を出力したユーザ数
            long lngSumScoredUser = 0;

            // 集計結果のカーソル先頭を位置へ移動
            logResult.beforeFirst();
            // レコード数ループ
            while (logResult.next()) {
                Date datStartDate = null;
                Date datEndDate = null;
                String strUserName = null;
                String strUserForeignId = null;
                String strGroups = null;
                String strGroupForeignId = null;
                String strStartDate = null;
                String strEndDate = null;
                String strAccessCount = null;
                String strResidanceTime = null;
                String strNewestScore = null;
                String strHighScore = null;
                String strCompPercent = null;
                String strPassPercent = null;
                String strAssign = null;
                long lngAUScoreCount = 0;

                // レコード情報取得
                IndividualLogGroupProgressUser dat = logResult.getIndividualLogGroupProgressUserList();
                // ユーザー
                strUserName = dat.getUser();
                // 外部ID
                strUserForeignId = dat.getUserForeign();
                // 所属グループ
                strGroups = dat.getGroupPath();
                // 外部ID
                strGroupForeignId = dat.getGroupForeignId();
                // 学習開始日時
                datStartDate = dat.getStartDate();
                // 最終アクセス日時
                datEndDate = dat.getEndDate();
                // アクセスが存在するか判定
                if (datStartDate != null) {
                    // 学習開始日時 日付型データをyyyy/mm/dd HH:mm:ss型に変換
                    strStartDate = XMODate.parseTime(datStartDate);
                    // 最終アクセス日時 日付型データをyyyy/mm/dd HH:mm:ss型に変換
                    strEndDate = XMODate.parseTime(datEndDate);
                    // アクセス回数
                    strAccessCount = Long.toString(dat.getAccessCount());
                    // 累積滞在時間
                    strResidanceTime = objFormat.format(dat.getResidanceTime()/(double)(1000*60));

					// 最新得点
					strNewestScore = dat.getNewestScore();
					// 最高得点
					strHighScore = dat.getHighScore();
					// 最新及び最高得点のどちらか一方でも得点が存在する場合、
					// 得点したユーザ数をカウントアップする。
					if (!(strNewestScore.equals("") && strHighScore.equals(""))) {
						lngAUScoreCount = dat.getAUScoreCount();
						lngSumScoredUser++;
					}
					// 最新得点を集計
					if(!strNewestScore.equals("")) {
						// 得点合計・平均用合算（ユーザあたりの満点を１００点に換算しておく。）
						fltSumNewestScore += Float.parseFloat(strNewestScore)/lngAUScoreCount;
						strNewestScore = 
							cominc.round(new Float(strNewestScore).doubleValue(),0) 
							+ "/" + Long.toString(lngAUScoreCount * 100);
					}
					// 最高得点を集計
					if(!strHighScore.equals("")) {
						// 得点合計・平均用合算（ユーザあたりの満点を１００点に換算しておく。）
						fltSumHighScore += Float.parseFloat(strHighScore)/lngAUScoreCount;
						strHighScore = 
							cominc.round(new Float(strHighScore).doubleValue(),0) 
							+ "/" + Long.toString(lngAUScoreCount * 100);
					}

                    // 完了ユニット数
                    strCompPercent = Long.toString(dat.getUnitComplete()) + "/" + Long.toString(dat.getAUCount());
                    // 合格ユニット数
                    strPassPercent = Long.toString(dat.getUnitPass()) + "/" + Long.toString(dat.getAUCount());
                    // AICCCOREテーブルにデータがあるユーザ数カウントアップ
                    lngSumAiccUser++;
                    // 合計・平均用合算
                    lngSumAccessCount += dat.getAccessCount();
                    lngSumResidanceTime += dat.getResidanceTime();
                    lngSumCompUnit += dat.getUnitComplete();
                    lngSumPassUnit += dat.getUnitPass();
                    lngSumAllUnit += dat.getAUCount();
                } else {
                    // アクセスがないので全て空文字
                    strStartDate = "";
                    strEndDate = "";
                    strAccessCount = "";
                    strResidanceTime = "";
                    strNewestScore = "";
                    strHighScore = "";
                    strCompPercent = "";
                    strPassPercent = "";
                }
                // アサイン
                strAssign = dat.getAssign();

                // CSV生成
                buffer.append( strUserName );
                buffer.append(",");
                buffer.append( strUserForeignId );
                buffer.append(",");
                buffer.append( strGroups );
                buffer.append(",");
                buffer.append( strGroupForeignId );
                buffer.append(",");
                buffer.append( strStartDate );
                buffer.append(",");
                buffer.append( strEndDate );
                buffer.append(",");
                buffer.append( strAccessCount );
                buffer.append(",");
                buffer.append( strResidanceTime );
                buffer.append(",");
                buffer.append( strNewestScore );
                buffer.append(",");
                buffer.append( strHighScore );
                buffer.append(",");
                buffer.append( strCompPercent );
                buffer.append(",");
                buffer.append( strPassPercent );
                buffer.append(",");
                buffer.append( strAssign );
                // 行区切り文字
                buffer.append(Constant.LINE_SEPARATOR);
            }
            // カーソルを先頭行の直前の行に移動する。
            logResult.beforeFirst();


            // =================================================================
            // CSV合計部生成
            buffer.append(IndividualLogGroupProgressConstant.STR_SUM_o);
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            // アクセス回数合計
            buffer.append( Long.toString(lngSumAccessCount) );
            buffer.append(",");
            // 累積滞在時間合計
            buffer.append( objFormat.format(lngSumResidanceTime/(double)(1000*60)) );
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            // 行区切り文字
            buffer.append(Constant.LINE_SEPARATOR);


            // =================================================================
            // CSV平均部
            String strAvgAccessCount = null;
            String strAvgResidanceTime = null;
            String strAvgNewestScore = null;
            String strAvgHighScore = null;
            String strAvgCompPercent = null;
            String strAvgPassPercent = null;
            // アクセス回数平均（アクセス回数合計／AICCCOREテーブルにデータのあるユーザ数）
            strAvgAccessCount = cominc.divideToString(lngSumAccessCount,lngSumAiccUser,1,"");
            if ( strAvgAccessCount.equals(LoLogConstant.STR_EMPTY_FIELD) ){
                //アクセス数デフォルト表示
                strAvgAccessCount = "0.0";
            }
            // 累積滞在時間平均（累積滞在時間合計／AICCCOREテーブルにデータのあるユーザ数）
            strAvgResidanceTime = cominc.divideToString(lngSumResidanceTime,(lngSumAiccUser*1000*60),1,"");
            if ( strAvgResidanceTime.equals(LoLogConstant.STR_EMPTY_FIELD) ){
                //アクセス数デフォルト表示
                strAvgResidanceTime = "0.0";
            }
            // 得点（最新）平均（得点（最新）合計／得点したユーザ数）
            strAvgNewestScore = cominc.divideToString(fltSumNewestScore,lngSumScoredUser,1,"");
            if ( strAvgNewestScore.equals(LoLogConstant.STR_EMPTY_FIELD) ){
                //アクセス数デフォルト表示
                strAvgNewestScore = "0.0/100";
            } else {
                //表示
                strAvgNewestScore = strAvgNewestScore+"/100";
            }
            // 得点（最高）平均（得点（最高）合計／得点したユーザ数）
            strAvgHighScore = cominc.divideToString(fltSumHighScore,lngSumScoredUser,1,"");
            if ( strAvgHighScore.equals(LoLogConstant.STR_EMPTY_FIELD) ){
                //アクセス数デフォルト表示
                strAvgHighScore = "0.0/100";
            } else {
                //表示
                strAvgHighScore = strAvgHighScore+"/100";
            }
            // 完了率平均（完了ユニット数合計／全ユーザのAU数の合計*100）
            strAvgCompPercent = cominc.divideToString(lngSumCompUnit*100,lngSumAllUnit,1,"");
            if ( strAvgCompPercent.equals(LoLogConstant.STR_EMPTY_FIELD) ){
                //アクセス数デフォルト表示
                strAvgCompPercent = "0.0%";
            } else {
                //カンマ区切り表示
                strAvgCompPercent = strAvgCompPercent + "%";
            }
            // 合格率平均（合格ユニット数合計／全ユーザのAU数の合計*100）
            strAvgPassPercent = cominc.divideToString(lngSumPassUnit*100,lngSumAllUnit,1,"");
            if ( strAvgPassPercent.equals(LoLogConstant.STR_EMPTY_FIELD) ){
                //アクセス数デフォルト表示
                strAvgPassPercent = "0.0%";
            } else {
                //カンマ区切り表示
                strAvgPassPercent = strAvgPassPercent + "%";
            }

            // CSV生成
            buffer.append(IndividualLogGroupProgressConstant.STR_AVG_o);
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            buffer.append(",");
            // アクセス回数平均
            buffer.append( strAvgAccessCount );
            buffer.append(",");
            // 累積滞在時間平均
            buffer.append( strAvgResidanceTime );
            buffer.append(",");
            // 得点（最新）平均
            buffer.append( strAvgNewestScore );
            buffer.append(",");
            // 得点（最高）平均
            buffer.append( strAvgHighScore );
            buffer.append(",");
            // 完了ユニット数平均
            buffer.append( strAvgCompPercent );
            buffer.append(",");
            // 合格ユニット数平均
            buffer.append( strAvgPassPercent );
            buffer.append(",");
            // 行区切り文字
            buffer.append(Constant.LINE_SEPARATOR);
            // 取得したBufferを文字列に変換
            retVal = buffer.toString();

        } catch (Exception e) {
            e.printStackTrace();
            retVal = "";
        }
        return retVal;
    }

}
