// <summary>ソースコード：ＨＹＳＳＯＰファイルベースライブラリ管理クラス</summary>
// <author>CommonMP</author>
using System;

using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSDBA;
using CommonMP.HYSSOP.CoreImpl.HSDBA.FileBase;
using CommonMP.HYSSOP.CoreImpl.HSTools;

namespace CommonMP.HYSSOP.CoreImpl.HSLibraryMng.FileBase
{
    /// <summary><para>class outline:</para>
    /// <para>ＨＹＳＳＯＰファイルベースライブラリ管理クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/10/13][新規作成]</para>
    /// <para>Remarks:</para>
    /// <para>データアクセス処理をサポートする</para>
    /// </remarks>
    public class HySFileLibraryManager : HySBaseLibraryManager
    {
        /// <summary>演算結果保存期間設定</summary>
        private static readonly HySString ENV_KEY_CALC_RESULT_DELETE_PERIOD = new HySString("CALC_RESULT_PRESERVED_PERIOD");

        /// <summary><para>method outline:</para>
        /// <para>DBAオブジェクトを作成する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> CreateDBAObject(csDBKindID, out csDBA)</para>
        /// </example>
        /// <param name="csDBKindID">DB種別ID</param>
        /// <param name="csDBA">DBAオブジェクト</param>
        /// <returns>true:DB種別IDに該当するDBAオブジェクトを生成した、false:対象外</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>DBAが利用できない場合、例外が発生する。</para>
        /// <para>サブクラスでオーバーライドする場合、サブクラスでサポートしない
        /// DB種別IDに対して基底クラスのメソッドを呼び出すこと。そうしないと
        /// 基本クラスでサポートしているDBが利用できなくなる。</para>
        /// </remarks>
        protected override bool CreateDBAObject(HySID csDBKindID, out HySCommonDBA csDBA)
        {
            csDBA = null;
            if (HySLibraryMngDefine.DB_KIND_CALC_RESULT_DATA.Equals(csDBKindID))
            {   // 演算結果
                csDBA = CreateCalResultDataDBA();
            }
            else if (HySLibraryMngDefine.DB_KIND_CALC_LOT_INFO.Equals(csDBKindID))
            {   // 演算ロット
                csDBA = CreateCalLotInfoDBA();
            }
            else if (HySLibraryMngDefine.DB_KIND_RIVER_CROSS_SECTION_DATA.Equals(csDBKindID))
            {   // 河道横断面
                csDBA = CreateCrossSectionDBA();
            }
            return (csDBA != null);
        }

        /// <summary><para>method outline:</para>
        /// <para>演算結果データDBDAオブジェクト生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> CreateCalResultDataDBA()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>DBAオブジェクト</returns>
        /// <exception cref="System.Exception">アセンブリがロードできなかった場合、例外がスローされる。</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private static HySCommonDBA CreateCalResultDataDBA()
        {
            return new HySCalResultDataDBA();
        }

        /// <summary><para>method outline:</para>
        /// <para>演算ロットデータDBDAオブジェクト生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> CreateCalLotInfoDBA()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>DBAオブジェクト</returns>
        /// <exception cref="System.Exception">アセンブリがロードできなかった場合、例外がスローされる。</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private static HySCommonDBA CreateCalLotInfoDBA()
        {
            return new HySCalLotInfoDBA();
        }

        /// <summary><para>method outline:</para>
        /// <para>河道横断面データDBAオブジェクト生成</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> CreateCrossSectionDBA()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>DBAオブジェクト</returns>
        /// <exception cref="System.Exception">アセンブリがロードできなかった場合、例外がスローされる。</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private static HySCommonDBA CreateCrossSectionDBA()
        {
            return new HySGeoRiverCrossSectionDBA();
        }

        /// <summary><para>method outline:</para>
        /// <para>終了処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = Terminate( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>演算ロット情報および演算結果データの削除処理を行う</para>
        /// </remarks>
        public override bool Terminate()
        {
            return CalcResultDataAutoDelete();
        }

        /// <summary><para>method outline:</para>
        /// <para>演算結果データ自動削除処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = CalcResultDataAutoDelete( ) </para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>true:正常、false:異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>演算ロット情報および演算結果データの削除処理を行う</para>
        /// </remarks>
        private bool CalcResultDataAutoDelete()
        {
            // 演算結果保存期間設定を取得する
            HySString csDeletePeriodSetting = HySEnvInf.GetEnvInf(ENV_KEY_CALC_RESULT_DELETE_PERIOD);
            if ((object)csDeletePeriodSetting == null)
            {
               // ver1.5 エラートレース日本語対応
                  string  DispStatement = Properties.HysMsgResources.STATEMENT_CONFIG_ITEM + "[" 
                  + string.Format("{0}" ,ENV_KEY_CALC_RESULT_DELETE_PERIOD.ToString()) + "]" + Properties.HysMsgResources.STATEMENT_MISSIGN ;
                   HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate", DispStatement );
                  // HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate",
                  //  string.Format("config item [{0}] missing", ENV_KEY_CALC_RESULT_DELETE_PERIOD.ToString()));
                return false;
            }
            // 整数に変換する
            int iDays;
            if (!int.TryParse(csDeletePeriodSetting.ToString(), out iDays))
            {
                // ver1.5 エラートレース日本語対応

                string  DispStatement = Properties.HysMsgResources.STATEMENT_CONFIG_ITEM
                + string.Format("[{0}={1}]" , ENV_KEY_CALC_RESULT_DELETE_PERIOD.ToString() ,  csDeletePeriodSetting.ToString())
                + Properties.HysMsgResources.STATEMENT_IS_INVALID ;

                HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate", DispStatement );
                
              //  HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate",
              //      string.Format("config item [{0}={1}] is invalid",
              //      ENV_KEY_CALC_RESULT_DELETE_PERIOD.ToString(),
              //      csDeletePeriodSetting.ToString()));
                return false;
            }
            // 削除対象期間を算出する
            long lSeconds = iDays * 24 * 60 * 60;
            HySTime csPeriodFrom = HySCalendar.CreateTime(1970, 1, 1, 0, 0, 0); // From: 最小値
            HySTime csPeriodTo = HySCalendar.CreateTime(DateTime.Today.ToString("yyyy/MM/dd")); // To: 本日の午前0時丁度を基準にする
            csPeriodTo.AddTime(lSeconds * -1);  // Toの時間をiDays日前にする
            csPeriodTo.AddTime(-1); // その前日の23時59分59秒にする

            // 演算ロット情報検索
            HySCommonDBA csCalLotInfoDBA = CreateCalLotInfoDBA();
            HySStockDataList csCalLotInfoList;
            HySQueryCtlData csCalLotInfoQuery = new HySQueryCtlData();
            csCalLotInfoQuery.SetIsMetaDataOnly(true);
            csCalLotInfoQuery.SetQueryEntryData(new HySQueryEntryData(HySCalLotInfoQueryFieldNames.PRESERVED_PERIOD_MODIFY_TIME, typeof(HySTime),
                HySQueryCompareMode.BETWEEN, new HySTime[] { csPeriodFrom, csPeriodTo }));
            csCalLotInfoQuery.SetQueryEntryData(new HySQueryEntryData(HySCalLotInfoQueryFieldNames.PRESERVED_PERIOD, typeof(HySStockData.PeservedPeriod),
                HySQueryCompareMode.EQUALS, HySStockData.PeservedPeriod.Temporary));
            if (!csCalLotInfoDBA.SearchList(csCalLotInfoQuery, out csCalLotInfoList))
            {
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate", Properties.HysMsgResources.STATEMENT_CALC_SERCH_ERR);
               // HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate", "CalcLotInfo search error");
                return false;
            }
            // 削除対象データが無い場合、終了する
            long lLotCount = csCalLotInfoList.GetCount();
            if (lLotCount == 0)
            {
                return true;
            }

            // 演算結果データを先に削除する
            HySCommonDBA csCalResultDataDBA = CreateCalResultDataDBA();
            csCalLotInfoList.SetCursorFirst();
            for (long lIdx = 0; lIdx < lLotCount; ++lIdx)
            {
                // 演算ロットIDを取得
                HySID csLotID = null;
                HySStockData csCalLotStockData = (HySStockData)csCalLotInfoList.GetCursorData();
                csCalLotInfoList.MoveCursorNext();

                long lKeyNumber = 0;
                HySDataHashTable csKeyInfo = csCalLotStockData.GetKeyInfo(ref lKeyNumber);
                if (lKeyNumber != 0)
                {
                    csLotID = (HySID)csKeyInfo.GetObject(HySCalLotInfoQueryFieldNames.LOT_ID);
                }
                if (csLotID == null)
                {                   
                   // ver1.5 エラートレース日本語対応
                    string  DispStatement = Properties.HysMsgResources.STATEMENT_WARNING + Properties.HysMsgResources.STATEMENT_CALCID_NO_SET
                        + "," + string.Format("CalcLotInfo.ID" + "={0}" , csCalLotStockData.GetID().ToString()) ;

                    HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate", DispStatement );

                  //  HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate",
                  //      string.Format("warning: CalcLotID not set, CalcLotInfo.ID={0}", csCalLotStockData.GetID().ToString()));

                    continue;
                }

                // 演算ロットID単位で削除を実行
                HySQueryCtlData csCalResultQuery = new HySQueryCtlData();
                csCalResultQuery.SetQueryEntryData(new HySQueryEntryData(HySCalResultDataQueryFieldNames.LOT_ID, typeof(HySID),
                    HySQueryCompareMode.EQUALS, csLotID));
                if (!csCalResultDataDBA.Delete(csCalResultQuery))
                {
                    // ver1.5 エラートレース日本語対応
                    string DispStatement = Properties.HysMsgResources.STATEMENT_WARNING + Properties.HysMsgResources.STATEMENT_CALCDATA_DEL_ERROR
                        + "," + "CalcLotID" + "=" + string.Format("{0}" , csLotID.ToString());
                    HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate", DispStatement );
                   // HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate",
                   //     string.Format("warning: CalcResultData delete error, CalcLotID={0}", csLotID.ToString()));
                    // ここでのエラーは続行する
                }
            }

            // 最初の検索条件で演算ロット情報を削除する
            if (!csCalLotInfoDBA.Delete(csCalLotInfoQuery))
            {
            // ver1.5 エラートレース日本語対応
                string DispStatement = Properties.HysMsgResources.STATEMENT_CALC_DEL_ERROR + ","
                    + Properties.HysMsgResources.STATEMENT_FROM + string.Format("{0}" ,HySCalendar.ToString(csPeriodFrom, HySCalendar.FORMAT.lSW_YEAR)) + ","
                    + Properties.HysMsgResources.STATEMENT_TO + string.Format("{0}" ,HySCalendar.ToString(csPeriodTo, HySCalendar.FORMAT.lSW_YEAR));

                HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate", DispStatement);

               // HySLog.LogOut(HySLog.ONLINE, GetType().Name, "Terminate",
               //     string.Format("CalcLotInfo delete error, From={0}, To={1}",
               //         HySCalendar.ToString(csPeriodFrom, HySCalendar.FORMAT.lSW_YEAR),
               //         HySCalendar.ToString(csPeriodTo, HySCalendar.FORMAT.lSW_YEAR)));
                return false;
            }
            return true;
        }
    }
}
