/*
 * 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.servlet.multipart;

// import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
// import java.io.BufferedOutputStream;
// import java.io.FileOutputStream;
import java.io.IOException;
import jakarta.servlet.ServletInputStream;
// import jakarta.servlet.http.HttpSession;				// 5.9.25.0 (2017/10/06) ｸﾗｳﾄﾞ対応

import org.opengion.fukurou.system.Closer ;				// 5.9.25.0 (2017/10/06) ｸﾗｳﾄﾞ対応
// import org.opengion.hayabusa.common.HybsSystem;			// 5.9.25.0 (2017/10/06) ｸﾗｳﾄﾞ対応
// import org.opengion.hayabusa.io.StorageAPI;			// 5.9.25.0 (2017/10/06) ｸﾗｳﾄﾞ対応
// import org.opengion.hayabusa.io.StorageAPIFactory;	// 5.9.25.0 (2017/10/06) ｸﾗｳﾄﾞ対応

import org.opengion.fukurou.model.FileOperation;			// 8.0.0.0 (2021/09/30)
import org.opengion.hayabusa.io.HybsFileOperationFactory;	// 8.0.0.0 (2021/09/30)

/**
 * ﾌｧｲﾙｱｯﾌﾟﾛｰﾄﾞ時のﾏﾙﾁﾊﾟｰﾄ処理のﾌｧｲﾙﾊﾟｰﾄ部品です｡
 *
 * ﾌｧｲﾙ情報を取り扱います｡
 *
 * @og.group その他機能
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class FilePart extends Part {

	private String filename;
	private final String filePath;
	private final String contentType;
	private final PartInputStream partInput;

	/**
	 * ﾌｧｲﾙﾊﾟｰﾄ部品 ｵﾌﾞｼﾞｪｸﾄを構築する､ｺﾝｽﾄﾗｸﾀｰ
	 *
	 * @param	name		Part名称
	 * @param	in			ServletInputStreamｵﾌﾞｼﾞｪｸﾄ
	 * @param	boundary	境界文字
	 * @param	contentType	ｺﾝﾃﾝﾂﾀｲﾌﾟ
	 * @param	filename	ﾌｧｲﾙ名
	 * @param	filePath	ﾌｧｲﾙﾊﾟｽ
	 * @throws IOException 入出力ｴﾗｰが発生したとき
	 */
	FilePart( final String name, final ServletInputStream in, final String boundary,
			final String contentType, final String filename, final String filePath)
											throws IOException {
		super(name);
		this.filename = filename;
		this.filePath = filePath;
		this.contentType = contentType;
		partInput = new PartInputStream(in, boundary);
	}

	/**
	 * ﾌｧｲﾙ名を取得します｡
	 *
	 * @return	ﾌｧｲﾙ名
	 */
	public String getFilename() {
		return filename;
	}

	/**
	 * ﾌｧｲﾙ名をｾｯﾄします｡
	 *
	 * @param  fname ﾌｧｲﾙ名
	 */
	public void setFilename( final String fname ) {
		filename = fname ;
	}

	/**
	 * ﾌｧｲﾙﾊﾟｽを取得します｡
	 *
	 * @return	ﾌｧｲﾙﾊﾟｽ
	 */
	public String getFilePath() {
		return filePath;
	}

	/**
	 * ｺﾝﾃﾝﾂﾀｲﾌﾟを取得します｡
	 *
	 * @return	ｺﾝﾃﾝﾂﾀｲﾌﾟ
	 */
	public String getContentType() {
		return contentType;
	}

	/**
	 * 入力ｽﾄﾘｰﾑを取得します｡
	 *
	 * @return	入力ｽﾄﾘｰﾑ
	 */
	public InputStream getInputStream() {
		return partInput;
	}

//	/**
//	 * ｸﾗｳﾄﾞｽﾄﾚｰｼﾞへのｱｯﾌﾟﾛｰﾄﾞ｡
//	 *
//	 * @og.rev 5.9.25.0 (2017/10/06) 追加
//	 *
//	 * @param storage		ｸﾗｳﾄﾞ種別
//	 * @param directory		ｱｯﾌﾟﾛｰﾄﾞ先ﾃﾞｨﾚｸﾄﾘ
//	 * @param hsession		ｾｯｼｮﾝ
//	 */
//	public void writeToCloud( final String storage, final String directory, final HttpSession hsession ) {
//		final StorageAPI storageApi = StorageAPIFactory.newStorageAPI( storage, HybsSystem.sys("CLOUD_BUCKET"), hsession );
//		storageApi.add( partInput, directory, filename, hsession );
//	}

	/**
	 * 指定のﾌｧｲﾙに書き出します｡
	 *
	 * @og.rev 5.10.9.0 (2019/03/01) ｸﾗｳﾄﾞｽﾄﾚｰｼﾞ対応を追加｡引数にstorage,bucketを追加｡
	 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加｡storageType , bucketName 削除
	 *
	 * @param	fileOrDirectory	出力先ﾌｧｲﾙ名/ﾃﾞｨﾚｸﾄﾘ名
//	 * @param	storage		ｸﾗｳﾄﾞﾌﾟﾗｸﾞｲﾝ名(ﾛｰｶﾙﾌｧｲﾙを強制する場合は､LOCAL を指定する)
//	 * @param	bucket		ﾊﾞｹｯﾄ名(ﾛｰｶﾙﾌｧｲﾙを強制する場合は､LOCAL を指定する)
	 * @param	useLocal	強制的にﾛｰｶﾙﾌｧｲﾙを使用する場合､true にｾｯﾄします｡
	 *
	 * @return	ｽﾄﾘｰﾑに書き出したﾊﾞｲﾄ数
	 * @throws  IOException 入出力ｴﾗｰが発生したとき
	 */
//	public long writeTo( final File fileOrDirectory ) throws IOException {
//	public long writeTo( final FileOperation fileOrDirectory, final String storage, final String bucket ) throws IOException {
	public long writeTo( final FileOperation fileOrDirectory, final boolean useLocal ) throws IOException {
		long written = 0;

//		OutputStream fileOut = null;
		try {
			// Only do something if this part contains a file
			if( filename != null ) {
				// Check if user supplied directory
//				File file;
				FileOperation file;
//				if( fileOrDirectory.isDirectory() ) {
				if(fileOrDirectory.isDirectory() || !fileOrDirectory.isFile()) {
					// Write it to that dir the user supplied,
					// with the filename it arrived with
					// 8.0.1.0 (2021/10/29) storageType , bucketName 削除
//					file = new File(fileOrDirectory, filename);
//					file = HybsFileOperationFactory.create(storage, bucket, fileOrDirectory, filename);
					file = HybsFileOperationFactory.create(useLocal, fileOrDirectory, filename);
				}
				else {
					// Write it to the file the user supplied,
					// ignoring the filename it arrived with
					file = fileOrDirectory;
				}
//				fileOut = new BufferedOutputStream(new FileOutputStream(file));
//				written = write(fileOut);
				file.write(partInput);
				written = file.length();
			}
		}
		finally {
//			Closer.ioClose( fileOut );		// 4.0.0 (2006/01/31) close 処理時の IOException を無視
			Closer.ioClose( partInput );	// V5 には入っていない…入れて大丈夫か？
		}
		return written;
	}

	/**
	 * 指定のｽﾄﾘｰﾑに書き出します｡
	 *
	 * @og.rev 6.3.9.1 (2015/11/27) 修飾子を､なし → private に変更｡
	 *
	 * @param	outStrm	OutputStreamｵﾌﾞｼﾞｪｸﾄ
	 *
	 * @return	ｽﾄﾘｰﾑに書き出したﾊﾞｲﾄ数
	 * @throws  IOException 入出力ｴﾗｰが発生したとき
	 */
	private long write( final OutputStream outStrm ) throws IOException {
		// decode macbinary if this was sent
		long size=0;
		int read;
		final byte[] buf = new byte[8 * 1024];
		while((read = partInput.read(buf)) != -1) {
			outStrm.write(buf, 0, read);
			size += read;
		}
		return size;
	}

	/**
	 * ﾌｧｲﾙかどうか｡
	 *
	 * @return	(常に true)
	 */
	@Override
	public boolean isFile() {
		return true;
	}
}
