// <summary>ソースコード：ＨＹＭＣＯ ファイルベースのライブラリ管理クラス</summary>
// <author>CommonMP</author>

using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;

using CommonMP.HYSSOP.Interface.HSData;
using CommonMP.HYSSOP.Interface.HSController;
using CommonMP.HYSSOP.Interface.HSLibraryMng;
using CommonMP.HYSSOP.CoreImpl.HSController;
using CommonMP.HYSSOP.CoreImpl.HSDBA;
using CommonMP.HYSSOP.CoreImpl.HSData;
using CommonMP.HYSSOP.CoreImpl.HSTools;

using CommonMP.HYMCO.Interface;
using CommonMP.HYMCO.Interface.LibraryMng;
using CommonMP.HYMCO.CoreImpl.LibraryMng;
using CommonMP.HYMCO.CoreImpl.Model;
using CommonMP.HYMCO.CoreImpl.DBA;
using CommonMP.HYMCO.CoreImpl.FigureUnity;
using CommonMP.HYMCO.CoreImpl.Data;
using CommonMP.HYMCO.CoreImpl.Data.LibraryCtl;
using CommonMP.HYMCO.CoreImpl.Data.StructInfo;
using CommonMP.HYMCO.CoreImpl.Data.ProjectCtl;
using CommonMP.HYMCO.CoreImpl.Data.Tool;

using CommonMP.HYMCO.CoreOptions.McDBA.FileDBA;
using CommonMP.HYSSOP.CoreImpl.HSLibraryMng;

namespace CommonMP.HYMCO.CoreOptions.LibraryMng.FileBaseLibraryManager
{
    /// <summary><para>class outline:</para>
    /// <para>ＨＹＭＣＯファイルベースライブラリ管理クラス</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2008/10/01][新規作成]</para>
    /// </remarks>
    public partial class McFileLibraryManager : McBaseLibraryManager
    {
        /// <summary><para>method outline:</para>
        /// <para>プロジェクトデータDBA取得</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>HySCommonDBA csDBA = GetProjectDataDBA()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>プロジェクトデータDBA</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        private static HySCommonDBA GetProjectDataDBA()
        {
            return new McFileProjectDataDBA();
        }

        /// <summary><para>method outline:</para>
        /// <para>DBAオブジェクトを生成する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>bool bRtn = CreateDBAObject(csDBKindID,csDBA) </para>
        /// </example>
        /// <param name="csDBKindID">DB種別</param>
        /// <param name="csDBA">DBAオブジェクト</param>
        /// <returns>true:成功、false:未サポートDB種別</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        protected override bool CreateDBAObject(HySID csDBKindID, out HySCommonDBA csDBA)
        {
            if (csDBKindID == HySLibraryMngDefine.DB_KIND_PROJECT_DATA)
            {
                csDBA = GetProjectDataDBA();
                return true;
            }
            else
            {
                csDBA = null;
                return false;
            }
        }

        /// <summary><para>method outline:</para>
        /// <para>DB保存データからIDを取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySID csID = GetIDFromStockData( csStockData ) </para>
        /// </example>
        /// <param name="csStockData">DB保存データ</param>
        /// <returns>データのユニークID</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>シミュレーションコンテナに格納されているプロジェクトIDを返す。</para>
        /// </remarks>
        protected override HySID GetIDFromStockData(HySStockData csStockData)
        {
            HySSimulationContainer csContainer = (HySSimulationContainer)csStockData.GetData();
            McProjectInfData csPrjInf = (McProjectInfData)csContainer.GetData(McDefine.HYM_DATA_PROJECT_INFO);
            return csPrjInf.GetProjectID();
        }

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para>McFileLibraryManager csManager = new McFileLibraryManager()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>McFileLibraryManager 生成されたインスタンス</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>無し</para>
        /// </remarks>
        public McFileLibraryManager(): base()
        {
        }

        /// <summary><para>method outline:</para>
        /// <para>任意処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = ArbJob( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>DB関連一般指示（CMND_DB_COMMON）に関するイベント処理を実行する</para>
        /// </remarks>
        public override bool ArbJob(HySEventObject csEvent)
        {
            bool bRtn = true;
            long lSubEventNo = csEvent.GetSubEventNo();

            // プロジェクトエクスポート
            if (McDefine.HYM_PRJDATA_EXPORT == lSubEventNo)
            {
                bRtn = ExportProject(csEvent);
            }
            // プロジェクトインポート
            else if (McDefine.HYM_PRJDATA_IMPORT == lSubEventNo || McDefine.HYM_PRJDATA_CONVERT == lSubEventNo)
            {
                bRtn = OpenExportFile(csEvent);
            }
            // プロジェクトインポート（ID設定後）
            else if (McDefine.HYM_PRJDATA_IMPORT_SET_ID == lSubEventNo)
            {
                bRtn = ImportProject(csEvent);
            }
            else
            {
                // 親クラスの任意処理に移行
                bRtn = base.ArbJob(csEvent);
            }

            return bRtn;
        }

        /// <summary><para>method outline:</para>
        /// <para>プロジェクトエクスポート処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = ExportProject( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>指定されたファイルに指定されたIDリストに対応するプロジェクトデータを出力する</para>
        /// </remarks>
        private bool ExportProject(HySEventObject csEvent)
        {
            string csMethod = "McFileLibraryManager.ExportProject";

            // エクスポートファイルパスとプロジェクトIDリストのデータ取得
            HySString csExportFilePath = (HySString)csEvent.GetData();
            HySDataLinkedList csIDList = (HySDataLinkedList)csEvent.GetSubData();
            // エクスポート用データリスト
            HySDataLinkedList csExportDataList = new HySDataLinkedList();

            HySCommonDBA csDBA = GetProjectDataDBA();

            // IDリストに含まれるIDに対応するプロジェクトデータを読み込む
            for (long lCount = 0; lCount < csIDList.GetCount(); lCount++)
            {
                HySID csID = (HySID)csIDList.GetData(lCount);

                // プロジェクトDBからIDを指定してデータを取得               
                HySStockData csStockData;
                bool bRtn = csDBA.GetData(csID, out csStockData);
                if (!bRtn)
                {
                    // 失敗した場合
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod,
                        Properties.HymcoFileLibraryResources.STATEMENT_PROJ_EXPORT_NG + "("
                      + Properties.HymcoFileLibraryResources.STATEMENT_DATA_GET_NG + ")" );
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "プロジェクトエクスポートエラー：データ取得失敗");
                    if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_NG, McDefine.HYM_PRJDATA_EXPORT))
                    {
                        // ver1.5 エラートレース日本語対応
                        HySLog.LogOut(HySLog.ONLINE, csMethod, 
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_ABNORMAL_REPORT 
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_EXPRT + ")" );
                       // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗（異常報告：プロジェクトエクスポート");
                    }
                    return false;
                }

                // プロジェクトデータ本体を取得
                HySSimulationDataContainer csSimulationData = (HySSimulationDataContainer)csStockData.GetData();
                csExportDataList.AddLast(csSimulationData);
            }

            HySFile csFile = new HySFile(csExportFilePath);
            // ファイルをオープン
            if (0 != csFile.Open(HySFile.OPEN_MODE.CREATE_NEW, HySFile.READ_WRITE_MODE.WRITE, HySFile.DIRECTORY_MODE.NOT_MK_DIR))
            {
                // 失敗した場合
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, csMethod,
                    Properties.HymcoFileLibraryResources.STATEMENT_PROJ_EXPORT_NG + Properties.HymcoFileLibraryResources.STATEMENT_FILE_OPEN_NG );
               // HySLog.LogOut(HySLog.ONLINE, csMethod, "プロジェクトエクスポートエラー：ファイルオープン失敗");
                if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_NG, McDefine.HYM_PRJDATA_EXPORT))
                {
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod, 
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_ABNORMAL_REPORT 
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_EXPRT + ")" );
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗（異常報告：プロジェクトエクスポート）");
                }
                return false;
            }

            // ファイルにデータリストを書き込む　
            if (!csFile.DataWrite(csExportDataList))
            {
                // 失敗した場合
                csFile.Close();
                csFile.Delete();

               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, csMethod, 
                    Properties.HymcoFileLibraryResources.STATEMENT_PROJ_EXPORT_NG + Properties.HymcoFileLibraryResources.STATEMENT_DATA_WRT_NG );
               // HySLog.LogOut(HySLog.ONLINE, csMethod, "プロジェクトエクスポートエラー：データ書き込み失敗");
                if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_NG, McDefine.HYM_PRJDATA_EXPORT))
                {
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod, 
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_ABNORMAL_REPORT 
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_EXPRT + ")" );
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗（異常報告：プロジェクトエクスポート）");
                }
                return false;
            }
            // ファイルをクローズする
            csFile.Close();

            // エクスポート完了報告イベントを送信
            if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_OK, McDefine.HYM_PRJDATA_EXPORT))
            {
                // 失敗した場合
                csFile.Delete();

               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, csMethod, 
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_NORMAL_REPORT 
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_EXPRT + ")" );
               // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗（正常報告：プロジェクトエクスポート）");
                return false;
            }

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>エクスポートファイルオープン</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = OpenExportFile( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>指定されたエクスポートファイルからプロジェクトデータリストを取得し、業務に送信する</para>
        /// </remarks>
        private bool OpenExportFile(HySEventObject csEvent)
        {
            string csMethod = "McFileLibraryManager.OpenExportFile";

            try
            {
                HySString csFilePath = (HySString)csEvent.GetData();
                HySFile csFile = new HySFile(csFilePath);
                if (0 != csFile.Open(HySFile.OPEN_MODE.OPEN, HySFile.READ_WRITE_MODE.READ, HySFile.DIRECTORY_MODE.NOT_MK_DIR))
                {
                    // エラーログ出力
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod,
                        Properties.HymcoFileLibraryResources.STATEMENT_PROJ_IMPORT_NG + Properties.HymcoFileLibraryResources.STATEMENT_FILE_OPEN_NG );
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "プロジェクトインポートエラー：ファイルオープン失敗");

                    // エラー報告イベント送信
                    if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_NG, McDefine.HYM_PRJDATA_IMPORT))
                    {
                       // ver1.5 エラートレース日本語対応
                        HySLog.LogOut(HySLog.ONLINE, csMethod,
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_ABNORMAL_REPORT 
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_IMPORT + ")" );
                       // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗(異常報告：プロジェクトインポート) ");
                    }
                    return false;
                }

                // プロジェクトデータリストをファイルから読み込む
                HySDataLinkedList csPrjDataList = csFile.DataRead() as HySDataLinkedList;
                csFile.Close();

                // ファイルフォーマットエラー時
                if (csPrjDataList == null)
                {
                    // エラーログ出力
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod, 
                        Properties.HymcoFileLibraryResources.STATEMENT_PROJ_EXPORT_NG + Properties.HymcoFileLibraryResources.STATEMENT_FILE_FORMAT_NG );
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "プロジェクトインポートエラー：ファイルフォーマット不正");

                    // エラー報告イベント送信
                    if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_NG, McDefine.HYM_PRJDATA_IMPORT))
                    {
                       // ver1.5 エラートレース日本語対応
                        HySLog.LogOut(HySLog.ONLINE, csMethod,
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_ABNORMAL_REPORT 
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_IMPORT + ")" );
                       // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗(異常報告：プロジェクトインポート) ");
                    }
                    return false;
                }

                // 業務へ送信しインポートデータのID設定をしてもらう
                long lSubNo = McDefine.HYM_PRJDATA_IMPORT_SET_ID;
                if (csEvent.GetSubEventNo() == McDefine.HYM_PRJDATA_CONVERT)
                {
                    lSubNo = McDefine.HYM_PRJDATA_CONVERT_SET_ID;
                }

                //if (!PutEvent(csEvent, HySEventObject.CMND_DB_COMMON, McDefine.HYM_PRJDATA_IMPORT_SET_ID, csPrjDataList))
                if (!PutEvent(csEvent, HySEventObject.CMND_DB_COMMON, lSubNo, csPrjDataList))
                {
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod, 
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_IMPORT + "(" 
                          + Properties.HymcoFileLibraryResources.STATEMENT_ID_SET + "))");
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗(プロジェクトインポート(ID設定)) ");
                    return false;
                }
            }
            catch (Exception ex)
            {
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, csMethod, 
                    Properties.HymcoFileLibraryResources.STATEMENT_CATCH_EXCEPTION + ":" + ex.Message + ex.StackTrace);
               // HySLog.LogOut(HySLog.ONLINE, csMethod, "catch Exception" + ":" + ex.Message + ex.StackTrace);
                // エラー報告イベント送信
                if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_NG, McDefine.HYM_PRJDATA_IMPORT))
                {
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod,
                        Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "(" + Properties.HymcoFileLibraryResources.STATEMENT_ABNORMAL_REPORT
                      + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_IMPORT + ")");
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗(異常報告：プロジェクトインポート) ");
                }
                return false;
            }

            return true;
        }

        /// <summary><para>method outline:</para>
        /// <para>プロジェクトインポート処理</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> bool bRtn = ImportProject( csEvent ) </para>
        /// </example>
        /// <param name="csEvent">送られたイベント</param>
        /// <returns>true:=正常, false:=異常</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>指定されたプロジェクトデータリストをDBに登録する</para>
        /// </remarks>
        private bool ImportProject(HySEventObject csEvent)
        {
            string csMethod = "McFileLibraryManager.ImportProject";

            // プロジェクトデータリストの取得
            HySDataLinkedList csProjectDataList = (HySDataLinkedList)csEvent.GetData();
            
            HySDataLinkedList csCmpImportDataList = new HySDataLinkedList();

            HySCommonDBA csDBA = GetProjectDataDBA();
            
            // プロジェクトデータを一件ずつ登録していく
            csProjectDataList.SetCursorFirst();
            for (int i = 0; i < csProjectDataList.GetCount(); i++)
            {
                HySSimulationDataContainer csDataCnt = (HySSimulationDataContainer)csProjectDataList.GetCursorData();
                HySStockData csStockData = new HySStockData((HySObjectKind)csDataCnt.GetSimKind(), (HySID)csDataCnt.GetID());
                csStockData.SetData(csDataCnt);

                // DB登録実行
                if (!csDBA.RegisterNew(csStockData))
                {
                    // 登録失敗時は処理中断、異常報告を行う

                    // エラーログ出力
                   // ver1.5 エラートレース日本語対応
                    HySLog.LogOut(HySLog.ONLINE, csMethod,
                        Properties.HymcoFileLibraryResources.STATEMENT_PROJ_IMPORT_NG + Properties.HymcoFileLibraryResources.STATEMENT_PROJ_REGIST_ERR );
                   // HySLog.LogOut(HySLog.ONLINE, csMethod, "プロジェクトインポートエラー：プロジェクト登録失敗");
                    
                    // インポート失敗イベントの送信
                    if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_NG, McDefine.HYM_PRJDATA_IMPORT, null, csProjectDataList, csCmpImportDataList))
                    {
                       // ver1.5 エラートレース日本語対応
                        HySLog.LogOut(HySLog.ONLINE, csMethod, 
                            Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                          + Properties.HymcoFileLibraryResources.STATEMENT_ABNORMAL_REPORT 
                          + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_IMPORT + ")" );
                       // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗(異常報告：プロジェクトインポート) ");
                    }
                    return false;
                }

                // インポート成功リストに追加
                csCmpImportDataList.AddLast(csDataCnt);

                csProjectDataList.MoveCursorNext();
            }

            // インポート完了イベントの送信
            if (!PutEvent(csEvent, HySEventObject.NOTICE_DB_OK, McDefine.HYM_PRJDATA_IMPORT, csProjectDataList))
            {
               // ver1.5 エラートレース日本語対応
                HySLog.LogOut(HySLog.ONLINE, csMethod, 
                     Properties.HymcoFileLibraryResources.STATEMENT_SEND_FAILURE + "("
                   + Properties.HymcoFileLibraryResources.STATEMENT_NORMAL_REPORT + Properties.HymcoFileLibraryResources.STATEMENT_PRJ_IMPORT + ")" );
               // HySLog.LogOut(HySLog.ONLINE, csMethod, "イベント送信失敗(正常報告：プロジェクトインポート) ");
                return false;
            }

            return true;
        }

    }
}
