/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.report2;

import java.io.File;

import org.opengion.fukurou.util.FileUtil;
import org.opengion.fukurou.util.StringUtil;
import org.opengion.fukurou.util.ZipArchive;					// 6.0.0.0 (2014/04/11) ZIP API変更
import static org.opengion.fukurou.system.HybsConst.CR ;		// 6.1.0.0 (2014/12/26)
import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.hayabusa.common.HybsSystemException;
// import org.opengion.hayabusa.report.CSVPrintRequest;			// 5.9.0.0 (2015/09/04) 8.0.1.0 (2021/10/29) 保留
import org.opengion.hayabusa.io.HybsFileOperationFactory;		// 8.0.1.0 (2021/10/29) ExecThread → ExecProcess
//import org.opengion.hayabusa.report.ExcelInsert;			// 7.4.4.0 (2021/06/30) Delete
//import org.opengion.hayabusa.report.ProgramRun;			// 7.4.4.0 (2021/06/30) Delete
//import org.opengion.hayabusa.report.RFIDPrintRequest;		// 7.4.4.0 (2021/06/30) Delete
// import static org.opengion.fukurou.system.HybsConst.FS;		// 6.1.0.0 (2014/12/26) refactoring // 8.0.0.0 (2021/07/31) Delete

/**
 * 帳票要求に設定された実行方法により､各種出力､Excel取り込み処理を行います｡
 * 1.出力
 *  雛形ﾌｧｲﾙを一時ﾃﾞｨﾚｸﾄﾘに展開した後､帳票ﾃﾞｰﾀを埋め込み､最後にOpenOffice.orgの
 *  ﾌﾟﾛｾｽを利用して出力を行います｡
 *  対応している出力方法は､印刷､PDF出力､Excel出力です｡
 *  一時ﾃﾞｨﾚｸﾄﾘは､ｼｽﾃﾑﾘｿｰｽのREPORT_FILE_URLで定義されたﾃﾞｨﾚｸﾄﾘです｡
 *  これが定義されていない場合は､ｼｽﾃﾑﾘｿｰｽのFILE_URLで定義されたﾃﾞｨﾚｸﾄ以下の/REPORTに
 *  展開されます｡
 *  一時ﾌｧｲﾙは､処理が正常に終了した場合､削除されます｡(ODS出力のみにした場合は､出力直前の
 *  ODSﾌｧｲﾙは残ります)
 *  処理でｴﾗｰが発生した場合は､一時ﾌｧｲﾙはﾃﾞﾊﾞｯｸﾞのため､削除されません｡
 * 2.取り込み
 *  旧帳票ｼｽﾃﾑの取り込み処理及びその後のPG起動を行います｡
 *
 * 実行方法により､出力､入力を行います｡
 *
 * @og.group 帳票ｼｽﾃﾑ
 *
 * @version  4.0
 * @author   Hiroki.Nakamura
 * @since    JDK1.6
 */
public class ExecProcess {

	/** 帳票処理ｷｭｰ */
	private final ExecQueue queue;

	/** 出力ﾀｲﾌﾟ */
	private final String type;

	private final long start = System.currentTimeMillis();		// 6.3.9.1 (2015/11/27) 修飾子を､なし → private に変更｡
	private final boolean debug;		// 4.3.0.0 (2008/07/15) ﾃﾞﾊﾞｯｸﾞの追加

	private final String outTemp ;		// 8.0.1.0 (2021/10/29)

	/**
	 * ｺﾝｽﾄﾗｸﾀ
	 *
	 * @og.rev 4.3.0.0 (2008/07/15)引数にdebugを追加
	 *
	 * @param qu		ExecQueueｵﾌﾞｼﾞｪｸﾄ
	 * @param debugFlag ﾃﾞﾊﾞｯｸﾞﾌﾗｸﾞ[true/false]
	 */
	public ExecProcess( final ExecQueue qu , final boolean debugFlag ) {
		queue = qu;
		type  = qu.getOutputType();
		debug = debugFlag;

		// 8.0.1.0 (2021/10/29)
		outTemp = HybsSystem.url2dir( StringUtil.nval( HybsSystem.sys( "REPORT_FILE_URL" ) ,HybsSystem.sys( "FILE_URL" ) + "REPORT/" ) )
			+ queue.getSystemId() + File.separator + queue.getListId() + File.separator + queue.getYkno();
	}

	/**
	 * 帳票処理ﾌﾟﾛｾｽを実行します｡
	 *
	 * @og.rev 4.3.0.0 (2008/07/15) debugの追加
	 * @og.rev 4.3.3.4 (2008/11/01) ODS出力追加
	 * @og.rev 5.1.2.0 (2010/01/01) 256ｼｰﾄを超えた場合の対応
	 * @og.rev 8.0.1.0 (2021/10/29) CSV出力対応(ﾕﾘﾆﾀ帳票)は､一旦保留にします｡
	 * @og.rev 8.0.1.0 (2021/10/29) OUT_ODS_XSLX (Excel2007形式) 評価用
	 */
	public void process() {
		// 処理開始
		addDebugMsg( "[INFO]EXEC-TIME:START=" + start );

		// 5.1.2.0 (2010/01/01) 基本的には1回で終了｡256ｼｰﾄを超える場合のみ内部でfalseを立てる(2回目を処理させる)
		queue.setEnd( true );

		/*
		 * ======================================================================
		 * = 出力処理
		 * ======================================================================
		 */
		// ﾊﾟｰｽ
//		if( ExecQueue.OUT_ODS_ONLY.equals( type )
//				|| ExecQueue.OUT_ODS_PRINT.equals( type ) || ExecQueue.OUT_ODS_PDF.equals( type ) || ExecQueue.OUT_ODS_EXCEL.equals( type )
//				|| ExecQueue.OUT_ODS_PRINT_PDF.equals( type ) || ExecQueue.OUT_ODS_ODS.equals( type ) ) {
//			parse();
//		}

		// 8.0.1.0 (2021/10/29) ﾊﾟｰｽ CSV出力を保留にしたので､印刷のみ以外はﾊﾟｰｽする｡
		if( !ExecQueue.OUT_PRINT_ONLY.equals( type ) ) {
			parse();
		}

		// 印刷
		if( ExecQueue.OUT_PRINT_ONLY.equals( type ) || ExecQueue.OUT_ODS_PRINT.equals( type ) ) {
			output( "PRINT" );
		}
		// PDF出力
		else if( ExecQueue.OUT_ODS_PDF.equals( type ) ) {
			output( "PDF" );
		}
		// EXCEL出力
		else if( ExecQueue.OUT_ODS_EXCEL.equals( type ) ) {
			output( "EXCEL" );
		}
		// 8.0.1.0 (2021/10/29) Excel2007出力
		else if( ExecQueue.OUT_ODS_XSLX.equals( type ) ) {
			output( "XSLX" );
		}
		// 印刷 + PDF出力
		else if( ExecQueue.OUT_ODS_PRINT_PDF.equals( type ) ) {
			output( "PRINT", "PDF" );
		}
		// 4.3.3.4 (2008/11/01) 追加 ODS出力
		else if( ExecQueue.OUT_ODS_ODS.equals( type ) ) {
			output( "ODS" );
		}

	//	/*
	//	 * ======================================================================
	//	 * = 取込処理
	//	 * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(EXCEL取込廃止)
	//	 * ======================================================================
	//	 */
		// 取込 7.4.4.0 (2021/06/30) Delete
	//	if( ExecQueue.IN_INPUT_ONLY.equals( type ) || ExecQueue.IN_INPUT_EXEC.equals( type ) ) {
	//		input();
	//	}

		// PG起動 7.4.4.0 (2021/06/30) Delete
	//	if( ExecQueue.IN_EXEC_ONLY.equals( type ) || ExecQueue.IN_INPUT_EXEC.equals( type ) ) {
	//		pgexec();
	//	}

	//	/*
	//	 * ======================================================================
	//	 * = RFID出力処理
	//	 * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(RFID出力廃止)
	//	 * ======================================================================
	//	 */
		// RFID出力 7.4.4.0 (2021/06/30) Delete
	//	if( ExecQueue.RFID_PRINT.equals( type ) || ExecQueue.RFID_ALLPRINT.equals( type )
	//			|| ExecQueue.RFID_ALLERASE.equals( type ) || ExecQueue.RFID_SEQERASE.equals( type ) ) {
	//		rfid();
	//	}

	//	// 8.0.1.0 (2021/10/29) CSV出力対応(ﾕﾘﾆﾀ帳票)は､一旦保留にします｡
	//	/*
	//	 * ======================================================================
	//	 * = CSV出力処理(ﾕﾆﾘﾀ 帳票形式のCSV)
	//	 * 5.9.4.2 (2016/01/13) Excel2追加
	//	 * ======================================================================
	//	 */
	//	if( ExecQueue.CSV_PRINT.equals( type ) || ExecQueue.CSV_PRINT_EXCEL.equals( type )
	//			|| ExecQueue.CSV_PRINT_PDF.equals( type ) || ExecQueue.CSV_PRINT_EXCEL2.equals( type ) ) {
	//		csv();
	//	}

		addDebugMsg( "[INFO]EXEC-TIME:END=" + System.currentTimeMillis() );
	}

	/**
	 * 雛形ﾌｧｲﾙを解析し､帳票ﾃﾞｰﾀを挿入します｡
	 *
	 * 雛形ﾌｧｲﾙは､ｸﾗｳﾄﾞ設定されていてもﾛｰｶﾙから取得します｡
	 *
	 * @og.rev 6.0.0.0 (2014/04/11) ZIP API変更
	 */
	private void parse() {
		final File templateFile = new File( queue.getTemplateName() + ".ods" );		// 6.0.0.0 (2014/04/11) ZIP API変更

//		final String tmp =
//			HybsSystem.url2dir( StringUtil.nval( HybsSystem.sys( "REPORT_FILE_URL" ) ,HybsSystem.sys( "FILE_URL" ) + "REPORT/" ) )
//			+ queue.getSystemId() + File.separator + queue.getListId() + File.separator + queue.getYkno();
//		final String tmpdir = tmp + File.separator;
		final String tmpdir = outTemp + File.separator;					// 8.0.1.0 (2021/10/29)
//		final File tmpdirFile = new File( tmp + File.separator );		// 6.0.0.0 (2014/04/11) ZIP API変更
		final File tmpdirFile = new File( tmpdir );						// 8.0.1.0 (2021/10/29)
//		final File tmpodsFile = new File( tmp + ".ods" );				// 6.0.0.0 (2014/04/11) ZIP API変更
		final File tmpodsFile = new File( outTemp + ".ods" );			// 8.0.1.0 (2021/10/29)

		// 一時ﾌｧｲﾙを削除(ｴﾗｰ発生時の前のﾌｧｲﾙを削除)
		FileUtil.deleteFiles( tmpdirFile );						// 6.0.0.0 (2014/04/11) ZIP API変更

		// 雛形ODSをﾃﾝﾎﾟﾗﾘﾌｫﾙﾀﾞに解凍
		ZipArchive.unCompress( tmpdirFile, templateFile );		// 6.0.0.0 (2014/04/11) ZIP API変更
		addDebugMsg( "[INFO]EXEC-TIME:UNCOMP=" + ( System.currentTimeMillis() - start ) );

		// DBTableModelのｾｯﾄ
		queue.setData();
		addDebugMsg( "[INFO]EXEC-TIME:DATA=" + ( System.currentTimeMillis() - start ) );

		// content.xml,meta.xmlのﾊﾟｰｽ
		final OdsContentParser contentParser = new OdsContentParser( queue, tmpdir );
		contentParser.exec();
		addDebugMsg( "[INFO]EXEC-TIME:PARSE=" + ( System.currentTimeMillis() - start ) );

		// 雛形ODSを再圧縮
		ZipArchive.compress( tmpdirFile, tmpodsFile );			// 6.0.0.0 (2014/04/11) ZIP API変更
		addDebugMsg( "[INFO]EXEC-TIME:COMP=" + ( System.currentTimeMillis() - start ) );

		// 一時ﾌｧｲﾙを削除
		FileUtil.deleteFiles( tmpdirFile );						// 6.0.0.0 (2014/04/11) ZIP API変更
		addDebugMsg( "[INFO]EXEC-TIME:DELETE=" + ( System.currentTimeMillis() - start ) );
	}

	/**
	 * 出力処理を行います｡
	 *
	 * @og.rev 4.2.3.1 (2008/06/04) 中間ﾌｧｲﾙの存在ﾁｪｯｸを追加
	 * @og.rev 4.3.0.0 (2008/07/18) ﾌﾟﾘﾝﾄ時のﾌﾟﾘﾝﾀ名ﾁｪｯｸ追加
	 * @og.rev 4.3.0.0 (2008/07/18) 出力ﾌｧｲﾙ名を指定していない場合に要求番号にする
	 * @og.rev 4.3.3.4 (2008/11/01) ODS出力追加
	 * @og.rev 5.1.2.0 (2010/01/01) 例外発生時にCalcｵﾌﾞｼﾞｪｸﾄをCloseしていないﾊﾞｸﾞを修正
	 * @og.rev 5.1.6.0 (2010/05/01) 変換ｸﾗｽの大幅見直しによる修正(元のｺｰﾄﾞも削除します)
	 * @og.rev 8.0.1.0 (2021/10/29) ﾛｰｶﾙﾌｧｲﾙとｸﾗｳﾄﾞﾌｧｲﾙ間の移動は､ExecProcess#output(String...) で行う｡
	 * @og.rev 8.0.1.0 (2021/10/29) OUT_ODS_XSLX (Excel2007形式) 評価用
	 *
	 * @param String... types
	 */
	private void output( final String... types ) {
//		final String tmpods =
//			HybsSystem.url2dir( StringUtil.nval( HybsSystem.sys( "REPORT_FILE_URL" ) ,HybsSystem.sys( "FILE_URL" ) + "REPORT/" ) )
//			+ queue.getSystemId() + File.separator + queue.getListId() + File.separator + queue.getYkno() + ".ods";

		final String tmpods = outTemp + ".ods";
		// 4.2.3.1 (2008/06/04) 中間ﾌｧｲﾙの存在ﾁｪｯｸ
		if( ! new File( tmpods ).exists() ){
			queue.addMsg( "中間ﾌｧｲﾙが存在しません｡" + tmpods + CR );
			throw new HybsSystemException();
		}

		// 変換ｸﾗｽの生成
		final DocConverter_OOO dc = new DocConverter_OOO( tmpods );
		try {
			// 起動
			dc.open();
			addDebugMsg( "[INFO]EXEC-TIME:OPEN=" + ( System.currentTimeMillis() - start ) );

			for( int i=0; i<types.length; i++ ) {
				if( "PRINT".equals( types[i] ) ) {
					// 4.3.0.0 (2008/07/18) ﾌﾟﾘﾝﾄ時のﾌﾟﾘﾝﾀ名ﾁｪｯｸ
					if( queue.getPrinterName() == null || queue.getPrinterName().isEmpty() ){
						queue.addMsg( "出力先ﾏｽﾀが正しく設定されていません｡" + CR );
						throw new Exception();
					}
					dc.print( queue.getPrinterName() );
				}
				else {
					// 8.0.1.0 (2021/10/29) ｸﾗｳﾄﾞｺﾋﾟｰをここで行う｡
					final String outFilename = queue.getOutputName();
					if( "PDF".equals( types[i] ) ) {
						dc.pdf( outFilename, queue.getPdfPasswd() );
					}
					else {
						dc.auto( outFilename );						// 8.0.1.0 (2021/10/29)
					}
	//				else if( "EXCEL".equals( types[i] ) ) {
	//					dc.xls( outFilename );
	//				}
	//				// 8.0.1.0 (2021/10/29) Excel2007出力
	//				else if( "XSLX".equals( types[i] ) ) {
	//					dc.xlsx( outFilename );
	//				}
	//				// 4.3.3.4 (2008/11/01) 追加
	//				else if( "ODS".equals( types[i] ) ) {
	//					dc.ods( outFilename );
	//				}
					HybsFileOperationFactory.local2cloud( false, () -> new File( outFilename ) );	// false:ｼｽﾃﾑ定義のｸﾗｳﾄﾞ設定に従う｡
				}
//				else if( "PDF".equals( types[i] ) ) {
//					dc.pdf( queue.getOutputName(), queue.getPdfPasswd() );
//				}
//				else if( "EXCEL".equals( types[i] ) ) {
//					dc.xls( queue.getOutputName() );
//				}
//				// 4.3.3.4 (2008/11/01) 追加
//				else if( "ODS".equals( types[i] ) ) {
//					dc.ods( queue.getOutputName() );
//				}
				addDebugMsg( "[INFO]EXEC-TIME:EXEC["+types[i]+"]=" + ( System.currentTimeMillis() - start ) );
			}

			// Calcを閉じる
			dc.close();
			addDebugMsg( "[INFO]EXEC-TIME:RELEASE=" + ( System.currentTimeMillis() - start ) );
		}
		catch( final Throwable th ) {
			// Calcを閉じる(ｴﾗｰ発生時)
			dc.close( true );
			queue.addMsg( "[INFO]EXEC-TIME:ERROR=" + ( System.currentTimeMillis() - start ) + CR );
			throw new HybsSystemException( th );
		}
		// 一時ﾌｧｲﾙの削除
		FileUtil.deleteFiles( new File( tmpods ) );
		addDebugMsg( "[INFO]EXEC-TIME:DELETE=" + ( System.currentTimeMillis() - start ) );
	}

	// /**
	// * 取込処理を行います｡
	// *
	// * @og.rev 4.3.0.0 (2008/07/15) debugの追加
	// * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(EXCEL取込廃止)
	// */
	// 7.4.4.0 (2021/06/30) Delete
	// private void input() {
	// 	boolean flag = false;

	// 	// ｴｸｾﾙ入力の基底となるﾊﾟｽ
	// 	final String excelinUrl = HybsSystem.url2dir( StringUtil.nval( HybsSystem.sys( "EXCEL_IN_FILE_URL" ), HybsSystem.sys( "FILE_URL" ) + "EXCELIN/" ) );
	// 	final String excelinDir = excelinUrl + queue.getSystemId() + FS + queue.getListId();

	// 	final ExcelInsert ei = new ExcelInsert( queue.getSystemId(), queue.getYkno(), queue.getListId(), excelinDir, false );
	// 	flag = ei.execute();
	// 	if( !flag ) {
	// 		queue.addMsg( ei.getErrMsg() );
	// 		queue.addMsg( "取り込み処理に失敗しました" );
	// 		throw new HybsSystemException();
	// 	}
	// 	addDebugMsg( "[INFO]EXEC-TIME:INPUT=" + ( System.currentTimeMillis() - start ) );
	// }

	// /**
	// * Excel取込後のPG起動処理を行います｡
	// *
	// * @og.rev 4.3.0.0 (2008/07/15) debugの追加
	// * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(EXCEL取込廃止)
	// */
	// 7.4.4.0 (2021/06/30) Delete
	// private void pgexec() {
	// 	boolean flag = false;

	// 	final ProgramRun pr = new ProgramRun( queue.getSystemId(), queue.getYkno(), queue.getListId(), false );
	// 	flag = pr.execute();
	// 	if( !flag ) {
	// 		queue.addMsg( "取り込み後のPG起動に失敗しました" );
	// 		queue.addMsg( pr.getErrMsg() );
	// 		throw new HybsSystemException();
	// 	}
	// 	addDebugMsg( "[INFO]EXEC-TIME:PGEXEC=" + ( System.currentTimeMillis() - start ) );
	// }

	// /**
	// * RFID出力処理を行います｡
	// *
	// * @og.rev 4.3.0.0 (2008/07/15) debugの追加
	// * @og.rev 4.3.3.0 (2008/10/01) 板金RFID対応
	// * @og.rev 5.4.3.9 (2012/01/25) 雛形ﾌｧｲﾙ名
	// * @og.rev 7.4.4.0 (2021/06/30) openGionV8事前準備(RFID出力廃止)
	// */
	// 7.4.4.0 (2021/06/30) Delete
	// private void rfid() {
	// 	boolean flag = false;

	// 	// RFIDPrintRequest rpr = new RFIDPrintRequest( queue.getSystemId(), queue.getYkno(), queue.getListId(), queue.getLang(), type, queue.getPrinterName(), false );
	// 	// 4.3.3.0 (2008/10/01) 板金RFID対応｡
	// 	// 5.4.3.9 (2012/01/25) 雛形ﾌｧｲﾙ名を渡す
	// 	final RFIDPrintRequest rpr = new RFIDPrintRequest( queue.getSystemId(), queue.getYkno(), queue.getListId(), queue.getLang(), type, queue.getPrtId()
	// 												 ,queue.getPrgDir(), queue.getPrgFile(), queue.getOutputName(),queue.getTemplateName(), false );
	// 	flag = rpr.initialDataSet();
	// 	if( flag ) {
	// 		flag = rpr.execute();
	// 	}
	// 	if( !flag ) {
	// 		queue.addMsg( "RFID出力処理に失敗しました" );
	// 		queue.addMsg( rpr.getErrMsg() );
	// 		throw new HybsSystemException();
	// 	}
	// 	addDebugMsg( "[INFO]EXEC-TIME:RFID=" + ( System.currentTimeMillis() - start ) );
	// }

	//	/**
	//	 * CSV出力処理を行います｡
	//	 *
	//	 * @og.rev 5.9.0.0 (2015/09/04)
	//	 * @og.rev 5.9.2.2 (2015/11/22) grpid,demgrp
	//	 * @og.rev 5.9.2.3 (2015/11/27) 件数対応
	//	 * @og.rev 8.0.1.0 (2021/10/29) CSV出力対応(ﾕﾘﾆﾀ帳票)は､一旦保留にします｡
	//	 */
	//	private void csv() {
	//		boolean flag = false;
	//
	//		final CSVPrintRequest rpr = new CSVPrintRequest( queue.getSystemId(), queue.getYkno(), queue.getListId(), queue.getLang(), type, queue.getPrtId()
	//							,queue.getPrgDir(), queue.getPrgFile(), queue.getOutputName(), queue.getTemplateName(), queue.getGrpId(), queue.getDmnGrp(), debug );
	//		flag = rpr.initialDataSet();
	//		if( flag ) {
	//			flag = rpr.execute();
	//		}
	//		if( !flag ) {
	//			queue.addMsg( "CSV出力処理に失敗しました" );
	//			queue.addMsg( rpr.getErrMsg() );
	//			throw new HybsSystemException();
	//		}
	//		queue.setExecRowCnt( rpr.getBodyCount() ); // 5.9.2.3 (2015/11/27)
	//
	//		addDebugMsg( "[INFO]EXEC-TIME:CSV=" + ( System.currentTimeMillis() - start ) );
	//	}

	/**
	 * ﾃﾞﾊﾞｯｸﾞ用のﾒｯｾｰｼﾞを出力します｡
	 *
	 * @param	msg	ﾒｯｾｰｼﾞ
	 */
	private void addDebugMsg( final String msg ) {
		if( debug ){
			queue.addMsg( msg + CR );
		}
	}
}
