package egovframework.rte.util.web.muilt.controllers;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.annotation.PreDestroy;

import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import egovframework.rte.util.fileupload.muilt.service.FileInfoVO;

/**
 * @file Name : ParallelGenericFileUploadController.java
 * @Description : ParallelGenericFileUploadController
 * @Modification Information
 * @
 * @  수정일         수정자                   수정내용
 * @ -------    --------    ---------------------------
 * @ 2009.03.05      이동도          최초 생성
 *
 *  @author 실행환경 개발팀 이동도
 *  @since 2009.03.05
 *  @version 1.0
 *  @see
 *  
 *  Copyright (C) 2009 by MOPAS  All right reserved.
 */

@Controller("parallelGenericFileUploadController")
public class ParallelGenericFileUploadController {

	/**
	 * Create a fixed size thread pool with numbers of threads equal to number
	 * of processors.
	 */

	private static final ExecutorService executor = Executors
			.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

	@SuppressWarnings("unchecked")
	@RequestMapping(value = "/upload/parallelGenericMulti.do")
	public String multipartProcess(
			final MultipartHttpServletRequest multiRequest) throws Exception {

		final long startTime = System.nanoTime();

		Assert.state(multiRequest.getParameter("type").equals(
						"parallelGenericFileMulti"),
						"type != parallelGenericFileMulti");

		/*
		 * extract files
		 */
		final Map<String, MultipartFile> files = multiRequest.getFileMap();
		Assert.notNull(files, "files is null");
		final int fileCount = files.size();

		Assert.state(fileCount > 0, "0 files exist");
		// fileCount
		System.out.println("##########################" + files.size());
		// FileMap
		System.out.println("##########################"
				+ multiRequest.getFileMap());

		/*
		 * process files in parallel! 여러개의 프로세스를 생성 파일이 C:\\temp에 있는 경우 중복하여 덮어씀
		 * 만약 파일이 추가되지 않을 경우 (fileCount)을 사용하여 예외처리함
		 */

//		List fileInfoList = new ArrayList();
//		String filePath;
//		for (final MultipartFile file : files.values()) {
//			filePath = "C:\\temp\\" + file.getOriginalFilename();
//			FileInfoVO fileInfoVO = new FileInfoVO();
//			fileInfoVO.setFilePath(filePath);
//			fileInfoVO.setFileName(file.getOriginalFilename());
//			fileInfoVO.setFileSize(file.getSize());
//			fileInfoList.add(fileInfoVO);
//		}
		
		
		for (final MultipartFile file : files.values()) {
			executor.execute(new Runnable() {

				public void run() {
					try {

						if (!"".equals(file.getOriginalFilename())) {
							file.transferTo(new File("C:\\temp\\"
									+ file.getOriginalFilename()));
							System.out.println(file.getOriginalFilename());
							System.out.println(file.getName());
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		}

		final long estimatedTime = System.nanoTime() - startTime;
		System.out.println(estimatedTime + " " + getClass().getSimpleName());

		return "success";
	}

	/**
	 * When Spring is shutdown (app undeploys) then shutdown thread pool too.
	 */
	@PreDestroy
	void shutdownAndAwaitTermination() {
		executor.shutdown();
		try {
			if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
				executor.shutdownNow();
				if (!executor.awaitTermination(60, TimeUnit.SECONDS))
					System.err.println("Pool did not terminate");
			}
		} catch (InterruptedException e) {
			executor.shutdownNow();
			Thread.currentThread().interrupt();
		}
	}
}