/////////////////////////////////////////////////////////////////
//Copyright (C) 2005 NTT CORPORATION.
//
//	ScormLOツールクラス
//
//		変更履歴
//			2005.02.16 新規作成  梅原 浩司
//
//	機能
//
//	このクラスはScormLOツールのクラスです。
//
////////////////////////////////////////////////////////////////

package jp.co.ntt.lms.xmf.tools.lo.scorm;

import java.io.*;
import java.util.*;

import javax.servlet.http.HttpServletRequest;

import jp.co.ntt.lms.lo.LOException;
import jp.co.ntt.lms.lo.scorm.ScormLoEnv;
import jp.co.ntt.lms.lo.scorm.ScormContentsExtract;
import jp.co.ntt.lms.xmf.tools.ToolBase;

/**
 *  ScormLOツールクラス
 * 
 *  このクラスはScormLOツールのクラスです。
 * 
 *  @author 梅原 浩司
 *  @version 1.0
 */
public class ScormLoTool extends ToolBase {
	
	/**
	 * Scormコンテンツパッケージファイルリストを取得する。
	 * @return ファイルリスト
	 * @throws LOException
	 */
	public File[] getScormContentsPackageFiles()
	throws LOException
	{
		String strManifestFtp = "";

		//  環境ファイルオブジェクトの取得
		ScormLoEnv objLoEnv = new ScormLoEnv();

		strManifestFtp = objLoEnv.getFtpMaterialPath();

		File currentDir = new File(strManifestFtp);
		File[] files = currentDir.listFiles();

		return files;
	}
	
	/**
	 * Scormコンテンツパッケージを展開する。
	 * @param request リクエストオブジェクト
	 * @return int エラー番号
	 * @throws Exception
	 */
	public int extractScormContentsPackage (HttpServletRequest request)
	throws Exception
	{
		boolean	bRet;
		String		strProperty = "";
		Properties	objProperty = null;


		//	使用する変数の定義
		String		strTempPath 			= null;	//	Tempファイルのパス
		String		strMaterialName 		= null;	//	教材名
		String		strFTPPath				= null;	//	ftp配下の圧縮教材を含むパス
		String		strContentFolderName	= null;	//	展開されたCPが格納されるフォルダ名
		String[] 	strFileNameList;				//	フォルダ配下のファイル名一覧
		int			intFileSize;					//	フォルダ配下のファイル数
		int			intErrorNumber			= -1;	//	エラー種別

		bRet = true;

		String		strManifestPath = null;	//manifestディレクトリのパス
		String		strScormCpPath= null;	//manifestのパスとZipファイル名を文字列連結
		String		strIMPath = null;	//imsmanifest.xmlのパス

		String		strScePath = null;	//sceのインストールディレクトリパス
		//Scorm.iniファイルからmanifestのパスを取得します・
		ScormLoEnv ObjEnv = new ScormLoEnv();
		strManifestPath = ObjEnv.getTempMaterialPath();

		//Scorm.iniファイルからsceのパスを取得します・
		strScePath = ObjEnv.getScePath();

		// ftpファイル名の取得
		String strCPName = request.getParameter("CPFILE");
		if(strCPName == null || strCPName.equals("")) {
			bRet			= false;
			intErrorNumber 	= 0;
		}
		
		else{ 

			if(strCPName.lastIndexOf(".") == -1){
				strCPName += ".zip";
			}

			//  環境ファイルオブジェクトの取得
			ScormLoEnv objLoEnv = new ScormLoEnv();

			strFTPPath = objLoEnv.getFtpMaterialPath();

			//	ftpフォルダ配下の圧縮ファイル名取得
			String strCPFilePath = strFTPPath + "/" + strCPName;

			strContentFolderName = objLoEnv.getTempMaterialPath();
			
			ScormContentsExtract cpext = new ScormContentsExtract();


			//	temp ファイルのパスを取得する
			strTempPath = strContentFolderName + "\\temp";
			File objTempFile = new File(strTempPath);

			// tempフォルダを作成する

			bRet = objTempFile.mkdir();

			//	Temp フォルダが作成できたら解凍を実施する。
			if (bRet == true)
			{
				//	☆圧縮ファイルを解凍する
				bRet = cpext.saveAllEntries(strCPFilePath, strTempPath);

				if (bRet == false)
				{
					//	圧縮ファイルの展開エラー
					intErrorNumber = 2;
				}
			}

			//==========================================================
			// 教材ID文字列をzipファイル名より取得する
			//		取得成功	bRetをtrue
			//		取得失敗	bRetをfalse
			//==========================================================

			int intSep		= strCPName.lastIndexOf(".");
			strMaterialName = strCPName.substring(0, intSep);

			if (strMaterialName == null)
			{
				bRet = false;
			}
			else
			{
				bRet = true;
			}

			if (bRet==true){

				//manifestのパスとZipファイル名を文字列連結　変数に格納
				strScormCpPath = strManifestPath + strMaterialName;

				//リネーム(ZIPファイル名)しようとする名前のディレクトリが
				//\xms2\scorm\manifestに存在するか確認

				//ファイルのオブジェクト化
				File objScormCPFile = new File(strScormCpPath);

				if (objScormCPFile.exists()){
				//リネーム(ZIPファイル名)しようとする名前のディレクトリがあれば
				//そのディレクトリの中にimsmanifest.xmlが存在しないか確認

					//imsmanifest.xmlのパスを変数に格納
					strIMPath = strScormCpPath + "\\imsmanifest.xml";

					//ファイルのオブジェクト化
					File objIMFile = new File(strIMPath);

					if (objIMFile.exists()){
					//imsmanifest.xmlが存在すれば
						//リネーム(ZIPファイル名)しようとする名前と同じ名前のディレクトリ
						//を削除

						//deleteALL()メソッド
						//ディレクトリ配下のファイル/ディレクトリ削除
								deleteALL(strScormCpPath);
						//リネーム(ZIPファイル名)と同じ名前のディレクトリを削除
								File fileB = new File(strScormCpPath);
								fileB.delete();
			
						// tempフォルダを取得した教材ID文字列にリネームする
						if (bRet == true){
							//	Tempフォルダを MaterailName の名前に変換する
							File objContextFile = new File(strContentFolderName + "/" + strMaterialName );

							bRet = objTempFile.renameTo(objContextFile);

							//	リネーム出来たかのチェック
							if (bRet == false)
							{
								intErrorNumber = 3;
							}
						}

					}else{
					//imsmanifest.xmlが存在しなければ
					//登録されているものとみなす

						//deleteALL()メソッド
						//tempディレクトリ配下のファイル/ディレクトリ削除
								deleteALL(strTempPath);
						//tempディレクトリの削除
								File fileC = new File(strTempPath);
								fileC.delete();

					}
				}else{
					//リネーム(ZIPファイル名)しようとする名前のディレクトリがなければ
					// tempフォルダを取得した教材ID文字列にリネームする
					
					if (bRet == true){
						//	Tempフォルダを MaterailName の名前に変換する
						File objContextFile = new File(strContentFolderName + "/" + strMaterialName );

						bRet = objTempFile.renameTo(objContextFile);

						//	リネーム出来たかのチェック
						if (bRet == false)
						{
							intErrorNumber = 3;
						}
					}

				}
			}

			// SCORMエンジンが同一サーバなら、zipファイルを転送して展開する。
			// 転送するzipファイル
			File objCPFile = new File(strCPFilePath);
			// SCORMエンジンデフォルトzip配置先
			//String strScePath = "D:\\wwwroot\\DocRoot\\sce";
			String strSceftpPath = strScePath + "ftp";
			File objSceTempDir = new File(strSceftpPath);

	       	if (objCPFile.exists() || objSceTempDir.exists() || objSceTempDir.isDirectory()){
	            FileInputStream fis = null;
	        	FileOutputStream fos = null;

				fis = new FileInputStream(objCPFile);
	        	fos = new FileOutputStream(new File(objSceTempDir, objCPFile.getName()));
	        	byte[] b = new byte[0x1000]; // バッファサイズは任意の値。

	        	while (true) {
	            		int len = fis.read(b);
	            		if (len == -1) {
	                		break;
	            		}
	            		fos.write(b, 0, len);
	        	}
	        	fis.close();
	        	fis = null;
	        	fos.close();
	        	fos = null;

				//	temp ファイルのパスを取得する
				String strSceContentFolderName = strScePath + "contents";
				String strSceTempPath = strSceContentFolderName + "_temp";
				File objSceTempPath = new File(strSceTempPath);

				// tempフォルダを作成する

				bRet = objSceTempPath.mkdir();

				//	Temp フォルダが作成できたら解凍を実施する。
				if (bRet == true)
				{
					//	☆圧縮ファイルを解凍する
					bRet = cpext.saveAllEntries(strCPFilePath, strSceTempPath);

					if (bRet == false)
					{
						//	圧縮ファイルの展開エラー
						intErrorNumber = 2;
					}
				}

				// tempフォルダを取得した教材ID文字列にリネームする

				if (bRet == true)
				{
				//	Tempフォルダを MaterailName の名前に変換する
					File objSceContextFile = new File(strSceContentFolderName + "/" + strMaterialName );

					bRet = objSceTempPath.renameTo(objSceContextFile);

					//	リネーム出来たかのチェック
					if (bRet == false)
					{
						intErrorNumber = 3;
					}
				}

				bRet = true;
			}
			else{
				bRet = false;			
			}
		}
		
		if (bRet) intErrorNumber = -1;
		
		context.put("strMaterialName", strMaterialName);
		
		return intErrorNumber;
	}

	/**
	 * ディレクトリ削除再帰メソッド
	 * @param path 削除パス
	 * @throws Exception
	 */
	private static void deleteALL( String path )throws Exception{
		String[] list = new File( path ).list();

		for ( int i = 0 ; i < list.length ; i++ ) {
			File fileA = new File( path + "\\" + list[i] );
			if ( fileA.isFile() ) {
				// ファイル削除
				fileA.delete();
			} else {
				// ディレクトリの場合、再帰する
				deleteALL( path + "\\" + list[i] );
				fileA.delete();
			}
		}
	}
}