/********************************************************************************* 
* Ephesoft is a Intelligent Document Capture and Mailroom Automation program 
* developed by Ephesoft, Inc. Copyright (C) 2015 Ephesoft Inc. 
* 
* This program is free software; you can redistribute it and/or modify it under 
* the terms of the GNU Affero General Public License version 3 as published by the 
* Free Software Foundation with the addition of the following permission added 
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK 
* IN WHICH THE COPYRIGHT IS OWNED BY EPHESOFT, EPHESOFT DISCLAIMS THE WARRANTY 
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 
* 
* This program is distributed in the hope that it will be useful, but WITHOUT 
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
* FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
* details. 
* 
* You should have received a copy of the GNU Affero General Public License along with 
* this program; if not, see http://www.gnu.org/licenses or write to the Free 
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
* 02110-1301 USA. 
* 
* You can contact Ephesoft, Inc. headquarters at 111 Academy Way, 
* Irvine, CA 92617, USA. or at email address info@ephesoft.com. 
* 
* The interactive user interfaces in modified source and object code versions 
* of this program must display Appropriate Legal Notices, as required under 
* Section 5 of the GNU Affero General Public License version 3. 
* 
* In accordance with Section 7(b) of the GNU Affero General Public License version 3, 
* these Appropriate Legal Notices must retain the display of the "Ephesoft" logo. 
* If the display of the logo is not reasonably feasible for 
* technical reasons, the Appropriate Legal Notices must display the words 
* "Powered by Ephesoft". 
********************************************************************************/ 

package com.ephesoft.dcma.imagemagick.imageClassifier;

import java.io.File;
import java.util.Map;

import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.ephesoft.dcma.batch.service.BatchSchemaService;
import com.ephesoft.dcma.core.common.DCMABusinessException;
import com.ephesoft.dcma.core.common.FileType;
import com.ephesoft.dcma.core.exception.DCMAApplicationException;
import com.ephesoft.dcma.da.service.BatchClassPluginConfigService;
import com.ephesoft.dcma.imagemagick.IImageMagickCommonConstants;
import com.ephesoft.dcma.imagemagick.ImageMagicProperties;
import com.ephesoft.dcma.imagemagick.constant.ImageMagicKConstants;
import com.ephesoft.dcma.util.CustomFileFilter;

/**
 * This Class generates thumbnails for all folders located at the folder location specified by the property
 * imagemagick.sample_base_folder_path of the property file imagemagick.properties. It is assumed that the sample folder will have the
 * following structure eg. C:\ephesoft-data\Samples\<batch-class-id>\<document-type>\<page-name> eg.
 * C:\ephesoft-data\Samples\1\India_Invoice\India_Invoice_First_Page Under this folder all the image files will be stored.The method
 * generateAllThumbnails parses all such document-type folders and finds all their page-type folders under these it finds the various
 * image files and creates thumbnails under a folder thumbs under the <page-name> folder.
 * 
 * @author Ephesoft
 * 
 */
public class SampleThumbnailGenerator {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	/**
	 * Instance of BatchClassPluginConfigService.
	 */
	@Autowired
	private BatchClassPluginConfigService batchClassPluginConfigService;

	/**
	 * Instance of BatchSchemaService.
	 */
	@Autowired
	private BatchSchemaService batchSchemaService;

	/**
	 * The sampleBaseFolderPath under this all the document types are located.
	 */
	private String sampleBaseFolderPath;
	/**
	 * Specifies weather PNG or TIF Thumbnails to be generated
	 */
	private String thumbnailType;
	/**
	 * The thumbnail height.
	 */
	private String thumbnailH;
	/**
	 * Thumbnails width.
	 */
	private String thumbnailW;

	/**
	 * @return the batchClassPluginConfigService
	 */
	public BatchClassPluginConfigService getBatchClassPluginConfigService() {
		return batchClassPluginConfigService;
	}

	/**
	 * @param batchClassPluginConfigService the batchClassPluginConfigService to set
	 */
	public void setBatchClassPluginConfigService(BatchClassPluginConfigService batchClassPluginConfigService) {
		this.batchClassPluginConfigService = batchClassPluginConfigService;
	}

	/**
	 * @return the batchSchemaService
	 */
	public BatchSchemaService getBatchSchemaService() {
		return batchSchemaService;
	}

	/**
	 * @param batchSchemaService the batchSchemaService to set
	 */
	public void setBatchSchemaService(BatchSchemaService batchSchemaService) {
		this.batchSchemaService = batchSchemaService;
	}

	/**
	 * This method is used to initialize the plugin specific properties from DB.
	 * 
	 * @param batchClassIdentifier String
	 * @throws DCMAApplicationException
	 */
	public void initializeProperties(String batchClassIdentifier) throws DCMAApplicationException {
		if (batchClassIdentifier == null || batchClassIdentifier.equals("0")) {
			logger.error("Invalid Batch class ID");
			throw new DCMAApplicationException("Invalide Batch class ID");
		} else {
			logger.info("Retrieving Image Magic Sample generation properties from DB");
			Map<String, String> properties = batchClassPluginConfigService.getPluginPropertiesForBatch(batchClassIdentifier,
					ImageMagicKConstants.CREATE_THUMBNAILS_PLUGIN);
			if (properties != null && properties.size() > 0) {
				sampleBaseFolderPath = batchSchemaService.getImageMagickBaseFolderPath(batchClassIdentifier, false);
				if (!(sampleBaseFolderPath != null && sampleBaseFolderPath.length() > 0)) {
					logger.error("Error retreiving sampleBaseFolderPath");
					throw new DCMAApplicationException("Error retreiving sampleBaseFolderPath");
				}
				thumbnailH = properties.get(ImageMagicProperties.CREATE_THUMBNAILS_COMP_THUMB_HEIGHT.getPropertyKey());
				if (!(thumbnailH != null && thumbnailH.length() > 0)) {
					logger.error("Error retreiving thumbnailH");
					throw new DCMAApplicationException("Error retreiving thumbnailH");
				}
				thumbnailType = properties.get(ImageMagicProperties.CREATE_THUMBNAILS_COMP_THUMB_TYPE.getPropertyKey());
				if (!(thumbnailType != null && thumbnailType.length() > 0)) {
					logger.error("Error retreiving thumbnailType");
					throw new DCMAApplicationException("Error retreiving thumbnailType");
				}
				thumbnailW = properties.get(ImageMagicProperties.CREATE_THUMBNAILS_COMP_THUMB_WIDTH.getPropertyKey());
				if (!(thumbnailW != null && thumbnailW.length() > 0)) {
					logger.error("Error retreiving thumbnailW");
					throw new DCMAApplicationException("Error retreiving thumbnailW");
				}

			} else {
				logger.error("Error retreiving Image Magic Sample generation  Properties from DB");
				throw new DCMAApplicationException("Error retreiving Image Magic Sample generation  Properties from DB");
			}
		}
	}

	/**
	 * Constructor.
	 * 
	 */
	public SampleThumbnailGenerator() {
	}

	/**
	 * Constructor.
	 * 
	 * @param sampleBaseFolderPath
	 * @param thumbnailType
	 * @param thumbnailH
	 * @param thumbnailW
	 */
	public SampleThumbnailGenerator(String sampleBaseFolderPath, String thumbnailType, String thumbnailH, String thumbnailW) {
		this.sampleBaseFolderPath = sampleBaseFolderPath;
		this.thumbnailType = thumbnailType;
		this.thumbnailH = thumbnailH;
		this.thumbnailW = thumbnailW;
	}

	/**
	 * This method generates all the thumbnails for all the document-types and all page-types under all document types. if the thumbs
	 * folder already exists it deletes it and creates it again.
	 * 
	 * @param batchClassId If present it generates thumbnails for that batch class. if empty or null generates thumbnails for all batch
	 *            classes
	 * @throws DCMAApplicationException
	 */
	public void generateAllThumbnails(String batchClassID) throws DCMAApplicationException {
		logger.info("Starting Generation of all Thumbnails for the sample Images.");
		File fSampleBaseFolderPath = new File(sampleBaseFolderPath);
		if (!fSampleBaseFolderPath.exists()) {
			logger.error("Folder Doesnot exist folder name=" + fSampleBaseFolderPath);
			throw new DCMABusinessException("Could not find folder-->" + fSampleBaseFolderPath);
		}

		int noOfThumbnailGenertd = 0;

		String[] listOfDocumetFolders = fSampleBaseFolderPath.list();
		logger.info("*Thumbnail generation for folder = " + fSampleBaseFolderPath);
		for (String documentFolder : listOfDocumetFolders) {
			logger.info("****Thumbnail generation for documet =" + documentFolder);
			File fDocumentFolder = new File(fSampleBaseFolderPath.getAbsolutePath() + File.separator + documentFolder);
			String[] listOfPageFolders = fDocumentFolder.list();
			for (String pageFolderName : listOfPageFolders) {
				logger.info("********Thumbnail generation started for all samples of page=" + pageFolderName);
				String pageFolderPath = fSampleBaseFolderPath.getAbsolutePath() + File.separator + documentFolder + File.separator
						+ pageFolderName;

				String thumbsFolderPath = pageFolderPath + File.separator + IImageMagickCommonConstants.THUMBS;
				File fthumbsFolder = new File(thumbsFolderPath);
				boolean thumbsFolderExists = false;
				if (fthumbsFolder.exists()) {
					// logger.info("********Deleting old thumbnails for page=" + pageFolderName);
					// FileUtils.deleteDirectoryAndContents(thumbsFolderPath);
					logger.info("Thumbs folder already exist for " + pageFolderPath);
					thumbsFolderExists = true;
					String[] thumbFiles = fthumbsFolder.list();
					if(thumbFiles != null && thumbFiles.length > 0){
						continue;
					}
				}
				if (!thumbsFolderExists) {
					fthumbsFolder.mkdir();
				}

				noOfThumbnailGenertd = noOfThumbnailGenertd + generateThumbnailsForFolder(pageFolderPath);
			}
		}

		logger.info("Total Thumbnails genertated =" + noOfThumbnailGenertd);
		logger.info("All Sample Thumbnails generated sucsesfully");

	}

	/**
	 * Generates thumbnails for a particular folder.
	 * 
	 * @param pageFolderPath
	 * @return
	 * @throws DCMAApplicationException
	 */
	private int generateThumbnailsForFolder(final String pageFolderPath) throws DCMAApplicationException {
		int numberOfThumbnailsGenerated = 0;
		File pageDirectory = new File(pageFolderPath);
		String[] listOfPageFiles = pageDirectory.list(new CustomFileFilter(false, FileType.TIF.getExtensionWithDot(),
				FileType.TIFF.getExtensionWithDot()));
		StringBuffer pageFilepath;
		StringBuffer thumbnailFilePath;
		for (String pageFileName : listOfPageFiles) {
			pageFilepath = new StringBuffer();
			thumbnailFilePath = new StringBuffer();
			pageFilepath.append(pageFolderPath).append(File.separator).append(pageFileName);

			thumbnailFilePath.append(pageFolderPath);
			thumbnailFilePath.append(File.separator);
			thumbnailFilePath.append(IImageMagickCommonConstants.THUMBS);
			thumbnailFilePath.append(File.separator);
			thumbnailFilePath.append(pageFileName);
			if (thumbnailType.equals(IImageMagickCommonConstants.EXT_TIF)) {
				thumbnailFilePath.append(IImageMagickCommonConstants.SUFFIX_THUMBNAIL_SAMPLE_TIF);
			}
			if (thumbnailType.equals(IImageMagickCommonConstants.EXT_PNG)) {
				thumbnailFilePath.append(IImageMagickCommonConstants.SUFFIX_THUMBNAIL_SAMPLE_PNG);
			}

			ConvertCmd convertcmd = new ConvertCmd();
			IMOperation operation = new IMOperation();
			operation.addImage();
			operation.thumbnail(Integer.parseInt(thumbnailH.trim()), Integer.parseInt(thumbnailW.trim()));
			operation.addImage();

			try {
				String[] listOfFiles = {pageFilepath.toString(), thumbnailFilePath.toString()};
				convertcmd.run(operation, (Object[]) listOfFiles);
				logger.info("***************Thumbnail generation of file " + pageFileName + " success");
				numberOfThumbnailsGenerated++;
			} catch (Exception ex) {
				logger.info("***************Thumbnail generation of file " + pageFileName + " Failiure");
				logger.error("Problem generating thumbnails for the File " + pageFilepath);
				throw new DCMAApplicationException("Problem generating thumbnails", ex);
			}

		}
		return numberOfThumbnailsGenerated;
	}

}
