package com.theorchard.javaowsassetbulkscript.logic;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;

import com.theorchard.javaowsassetbulkscript.LabelStatusRepository;
import com.theorchard.javaowsassetbulkscript.UnknownOrchardUpcRepository;
import com.theorchard.javaowsassetbulkscript.models.ImportedProduct;
import com.theorchard.javaowsassetbulkscript.models.LabelStatus;
import com.theorchard.javaowsassetbulkscript.models.UnknownOrchardUpc;

public class ReportBuilder {

	private static final String ASSET_MISSING_ERR_MSG = "Product not found at The Orchard";

	private static final int COLUMN_EXTRA_WIDTH = 1000;

	private static final File LABEL_STATUS_FILE = new File(System.getProperty("user.home") + "/labelStatus.xls");
	
    @Autowired
    private LabelStatusRepository labelStatusRepository;
    
    @Autowired
    private UnknownOrchardUpcRepository unknownOrchardUpcRepository;
    
	
    File buildLabelStatusReport() {
    	Iterable<LabelStatus> doneTable = labelStatusRepository.findByStatus("Done");
    	Iterable<LabelStatus> errorTable = labelStatusRepository.findByStatus("Error");
    	Iterable<LabelStatus> exceptionTable = labelStatusRepository.findByStatus("Exception");
    	Iterable<LabelStatus> transferringTable = labelStatusRepository.findByStatus("Transferring");
    	Iterable<LabelStatus> queuedTable = labelStatusRepository.findByStatus("Queued");
    	Iterable<UnknownOrchardUpc> unknownOrchardUpcsTable = unknownOrchardUpcRepository.findAll();
    	Iterable<LabelStatus> allLabelsTable = labelStatusRepository.findAll();

    	if (!LABEL_STATUS_FILE.exists()) {
    		try {
				LABEL_STATUS_FILE.createNewFile();
			} catch (IOException e) {
				System.err.println("Error occured trying to create new File " + LABEL_STATUS_FILE.getAbsolutePath());
				e.printStackTrace();
			}
    	}
    	Workbook workbook = new HSSFWorkbook();
    	CellStyle generalStyle = buildGeneralCellStyle(workbook);
    	CellStyle dateStyle = buildDateStyle(workbook);
    	
    	Sheet doneSheet = workbook.createSheet("Done");
    	Sheet errorSheet = workbook.createSheet("Error");
    	Sheet exceptionSheet = workbook.createSheet("Exception");
    	Sheet transferringSheet = workbook.createSheet("Transferring");
    	Sheet queuedSheet = workbook.createSheet("Queued");
    	
    	Sheet brokenProductSheet = workbook.createSheet("Broken Products");
    	Sheet onlyAssetsMissingProductSheet = workbook.createSheet("Assets missing");
    	
    	Sheet unknownOrchardUpcsSheet = workbook.createSheet("Unknown Orchard UPCs");
    	Sheet assetIngestionStatusSheet = workbook.createSheet("Asset Ingestion Status");
    	
    	FileOutputStream fileOut = null;
		try {
			fileOut = new FileOutputStream(LABEL_STATUS_FILE);
		} catch (FileNotFoundException e1) {
			System.err.println("Error occured trying to create FileOutputStream for File " + LABEL_STATUS_FILE.getAbsolutePath());
			e1.printStackTrace();
		}
		
		Iterable<LabelStatus> missingAssetsOnlyTable = extractMissingAssetsOnlyFromErrorTable(errorTable);
		Iterable<LabelStatus> otherwiseBrokenLabelsTable = extractOtherErrorsFromErrorTable(errorTable, missingAssetsOnlyTable);
		
    	writeStatusToDoneSheet(doneTable, missingAssetsOnlyTable, doneSheet, generalStyle, dateStyle);
    	writeStatusToErrorSheet(otherwiseBrokenLabelsTable, errorSheet, generalStyle, dateStyle);
    	
    	writeStatusToSheet(exceptionTable, exceptionSheet, generalStyle, dateStyle);
    	writeStatusToSheet(transferringTable, transferringSheet, generalStyle, dateStyle);
    	writeStatusToSheet(queuedTable, queuedSheet, generalStyle, dateStyle);
    	
    	writeBrokenProductsSheet(otherwiseBrokenLabelsTable, brokenProductSheet, generalStyle, dateStyle);
    	writeMissingAssetsSheet(missingAssetsOnlyTable, onlyAssetsMissingProductSheet, generalStyle, dateStyle);
    	
    	writeUnknownOrchardUpcsSheet(unknownOrchardUpcsTable, unknownOrchardUpcsSheet, generalStyle);
    	writeAssetIngestionStatusSheet(allLabelsTable, assetIngestionStatusSheet, generalStyle);
    	
    	try {
			workbook.write(fileOut);
			workbook.close();
			fileOut.close();
    	} catch (IOException e) {
			System.err.println("Error occured trying to write file " +  LABEL_STATUS_FILE.getAbsolutePath());
			e.printStackTrace();
		}
    	return LABEL_STATUS_FILE;
    }
	
    
    private Iterable<LabelStatus> extractOtherErrorsFromErrorTable(Iterable<LabelStatus> errorTable,
			Iterable<LabelStatus> missingAssetsOnlyTable) {
		
    	List<LabelStatus> otherwiseBrokenLabels = new LinkedList<>();
		List<LabelStatus> missingAssetsList =  new LinkedList<LabelStatus>();
		missingAssetsOnlyTable.forEach(missingAssetsList::add);
		
		for (LabelStatus errorLabel : errorTable) {
			if (!missingAssetsList.contains(errorLabel)) {
				otherwiseBrokenLabels.add(errorLabel);
			}
		}
		return otherwiseBrokenLabels;
	}


	private Iterable<LabelStatus> extractMissingAssetsOnlyFromErrorTable(Iterable<LabelStatus> errorTable) {
		
    	List<LabelStatus> missingProducts = new LinkedList<LabelStatus>();
    	
    	for (LabelStatus labelStatus : errorTable) {
    		if (!labelStatus.getMessage().startsWith("Found 0 for")) {
    			continue;
    		}
    		Collection<ImportedProduct> importedProducts = labelStatus.getImportedProducts();
    		boolean onlyMissingAssetsError = true;
    		for (ImportedProduct product : importedProducts) {
    			if (!("Assets verified".equals(product.getMessage()) || 
    					ASSET_MISSING_ERR_MSG.equals(product.getMessage()))) {
    				onlyMissingAssetsError = false;
    			}
    		}
    		if (onlyMissingAssetsError) {
    			missingProducts.add(labelStatus);
    		}
    	}
    	
		return missingProducts;
	}


	private void writeUnknownOrchardUpcsSheet(Iterable<UnknownOrchardUpc> table,
			Sheet sheet, CellStyle generalStyle) {
		int curRow = 0;
    	Row header = sheet.createRow(curRow);
    	
    	createGeneralStringCell(generalStyle, "Orchard UPC", header, 0);
    	createGeneralStringCell(generalStyle, "finetunes label ID", header, 1);
    	createGeneralStringCell(generalStyle, "vendor ID", header, 2);
    	createGeneralStringCell(generalStyle, "mapped finetunes UPC", header, 3);


		curRow++;
		
		for (UnknownOrchardUpc unknownOrchardUpc : table) {
			Row row = sheet.createRow(curRow);
			
			long upc = unknownOrchardUpc.getUpc();
			String ftLabelId = unknownOrchardUpc.getLabelId();
			long vendorId = unknownOrchardUpc.getVendorId();
			String finetunesUpc = unknownOrchardUpc.getFinetunesUpc();

			createGeneralNumericCell(generalStyle, upc, row, 0);
			createGeneralStringCell(generalStyle, ftLabelId, row, 1);
			createGeneralNumericCell(generalStyle, vendorId, row, 2);

			createGeneralStringCell(generalStyle, finetunesUpc, row, 3);

			
			curRow++;
		}
		
		autosizeColumns(sheet, 3);

	}


	private void writeStatusToDoneSheet(Iterable<LabelStatus> doneTable, Iterable<LabelStatus> missingAssetsLabelsTable,
			Sheet doneSheet, CellStyle generalStyle, CellStyle dateStyle) {
		
		int curRow = 0;
    	Row header = doneSheet.createRow(curRow);
    	createGeneralStringCell(generalStyle, "finetunes ID", header, 0);
    	createGeneralStringCell(generalStyle, "vendor ID", header, 1);
    	createGeneralStringCell(generalStyle, "update date", header, 2);
    	createGeneralStringCell(generalStyle, "# successful products", header, 3);
    	createGeneralStringCell(generalStyle, "# missing products at The Orchard", header, 4);
    	createGeneralStringCell(generalStyle, "# unknown Orchard UPCs", header, 5);
    	createGeneralStringCell(generalStyle, "Is incomplete", header, 6);
    	
		curRow++;
		
		// All good, completely clean, done labels
    	for (LabelStatus status : doneTable) {
    		String labelId = status.getLabelId();
    		int vendorId = status.getVendorId();
    		Date updateDate = status.getUpdateDate();
    		int goodProducts = 0;
    		int assetsMissing = 0;
    		// Should not be necessary to count, but might indicate bugs
    		for (ImportedProduct product : status.getImportedProducts()) {
    			String prouctStatus = product.getStatus();
    			if ("Good".equals(prouctStatus)) {
    				goodProducts++;
    			} else if ("Error".equals(prouctStatus) && ASSET_MISSING_ERR_MSG.equals(product.getMessage())) {
    				assetsMissing++;
    			}
    		}

    		int unknownUpcs = 0;
    		List<UnknownOrchardUpc> unknownUpcsTable = unknownOrchardUpcRepository.findByLabelId(labelId);
    		for (UnknownOrchardUpc unknownUpc : unknownUpcsTable) {
    			if (unknownUpc.getFinetunesUpc() == null) {
    				unknownUpcs++;
    			}
    		}

    			
    		Row row = doneSheet.createRow(curRow);
    		
    		createGeneralStringCell(generalStyle, labelId, row, 0);
    		createGeneralNumericCell(generalStyle, vendorId, row, 1);
    		createDateCell(dateStyle, updateDate, row, 2);
    		createGeneralNumericCell(generalStyle, goodProducts, row, 3);
    		createGeneralNumericCell(generalStyle, assetsMissing, row, 4);
    		createGeneralNumericCell(generalStyle, unknownUpcs, row, 5);
    		createGeneralStringCell(generalStyle, "", row, 6);

    		curRow++;
    	}
		
    	// Labels that only fall in the "Missing assets at The Orchard" category
		for (LabelStatus missingAssetsLabel : missingAssetsLabelsTable) {
			String labelId = missingAssetsLabel.getLabelId();
    		int vendorId = missingAssetsLabel.getVendorId();
    		Date updateDate = missingAssetsLabel.getUpdateDate();
    		int goodProducts = 0;
    		int assetsMissing = 0;
    		for (ImportedProduct product : missingAssetsLabel.getImportedProducts()) {
    			String prouctStatus = product.getStatus();
    			if ("Good".equals(prouctStatus)) {
    				goodProducts++;
    			} else if ("Error".equals(prouctStatus) && ASSET_MISSING_ERR_MSG.equals(product.getMessage())) {
    				assetsMissing++;
    			}
    		}

    		int unknownUpcs = 0;
    		List<UnknownOrchardUpc> unknownUpcsTable = unknownOrchardUpcRepository.findByLabelId(labelId);
    		for (UnknownOrchardUpc unknownUpc : unknownUpcsTable) {
    			if (unknownUpc.getFinetunesUpc() == null) {
    				unknownUpcs++;
    			}
    		}

    			
    		Row row = doneSheet.createRow(curRow);
    		
    		createGeneralStringCell(generalStyle, labelId, row, 0);
    		createGeneralNumericCell(generalStyle, vendorId, row, 1);
    		createDateCell(dateStyle, updateDate, row, 2);
    		createGeneralNumericCell(generalStyle, goodProducts, row, 3);
    		createGeneralNumericCell(generalStyle, assetsMissing, row, 4);
    		createGeneralNumericCell(generalStyle, unknownUpcs, row, 5);
    		createGeneralStringCell(generalStyle, "Yes", row, 6);

    		curRow++;
		}
		
		autosizeColumns(doneSheet, 6);
	}


	private void writeStatusToErrorSheet(Iterable<LabelStatus> table, Sheet errorSheet,
			CellStyle generalStyle, CellStyle dateStyle) {
		
		int curRow = 0;
    	Row header = errorSheet.createRow(curRow);
    	
    	createGeneralStringCell(generalStyle, "finetunes ID", header, 0);
    	createGeneralStringCell(generalStyle, "vendor ID", header, 1);
    	createGeneralStringCell(generalStyle, "label status", header, 2);
    	createGeneralStringCell(generalStyle, "update date", header, 3);
    	createGeneralStringCell(generalStyle, "message", header, 4);
    	createGeneralStringCell(generalStyle, "# successful products", header, 5);
    	createGeneralStringCell(generalStyle, "# broken products", header, 6);
    	createGeneralStringCell(generalStyle, "# missing products at The Orchard", header, 7);
    	createGeneralStringCell(generalStyle, "# unknown Orchard UPCs", header, 8);
    	
		curRow++;
		
		for (LabelStatus status : table) {
    		String labelId = status.getLabelId();
    		int vendorId = status.getVendorId();
    		String labelStatus = status.getStatus();
    		Date updateDate = status.getUpdateDate();
    		String message = status.getMessage();
    		int goodProducts = 0;
    		int errorProducts = 0;
    		int missingProducts = 0;
    		for (ImportedProduct product : status.getImportedProducts()) {
    			String productStatus = product.getStatus();
    			if ("Good".equals(productStatus)) {
    				goodProducts++;
    			} else if ("Error".equals(productStatus)) {
    				if (ASSET_MISSING_ERR_MSG.equals(product.getMessage())) {
    					missingProducts++;
    				} else {
    					errorProducts++;
    				}
    			}
    		}
    		
    		int unknownUpcs = 0;
    		List<UnknownOrchardUpc> unknownUpcsTable = unknownOrchardUpcRepository.findByLabelId(labelId);
    		for (UnknownOrchardUpc unknownUpc : unknownUpcsTable) {
    			if (unknownUpc.getFinetunesUpc() == null) {
    				unknownUpcs++;
    			}
    		}
    			
    		Row row = errorSheet.createRow(curRow);
    		
    		createGeneralStringCell(generalStyle, labelId, row, 0);
    		createGeneralNumericCell(generalStyle, vendorId, row, 1);
    		createGeneralStringCell(generalStyle, labelStatus, row, 2);
    		createDateCell(dateStyle, updateDate, row, 3);
    		createGeneralStringCell(generalStyle, message, row, 4);
    		createGeneralNumericCell(generalStyle, goodProducts, row, 5);
    		createGeneralNumericCell(generalStyle, errorProducts, row, 6);
    		createGeneralNumericCell(generalStyle, missingProducts, row, 7);
    		createGeneralNumericCell(generalStyle, unknownUpcs, row, 8);
    		
    		curRow++;
    	}
		
		autosizeColumns(errorSheet, 8);
		
	}


	private void writeBrokenProductsSheet(Iterable<LabelStatus> errorTable, Sheet sheet, CellStyle generalStyle, CellStyle dateStyle) {
    	
    	int curRow = 0;
    	Row header = sheet.createRow(curRow);
    	
    	createGeneralStringCell(generalStyle, "finetunes ID", header, 0);
    	createGeneralStringCell(generalStyle, "vendor ID", header, 1);
    	createGeneralStringCell(generalStyle, "finetunes album ID", header, 2);
    	createGeneralStringCell(generalStyle, "product ID", header, 3);
    	createGeneralStringCell(generalStyle, "UPC", header, 4);
    	createGeneralStringCell(generalStyle, "Message (Label Level)", header, 5);
    	createGeneralStringCell(generalStyle, "Message (Product Level)", header, 6);
    	createGeneralStringCell(generalStyle, "import Date", header, 7);
    	
		curRow++;
    	
    	for (LabelStatus entry : errorTable) {
    		String labelId = entry.getLabelId();
    		int vendorId = entry.getVendorId();
    		String labelMessage = entry.getMessage();
    		Collection<ImportedProduct> importedProducts = entry.getImportedProducts();
    		for (ImportedProduct product : importedProducts) {
    			
    			if (!"Error".equals(product.getStatus()) || 
    					ASSET_MISSING_ERR_MSG.equals(product.getMessage())) {
    				// Just include the broken products of this label, ignore product not found errors
    				continue;
    			}
    			
    			String albumId = product.getReleaseId();
    			int productId = product.getProductId();
    			String upc = product.getUpc();
    			String productMessage = product.getMessage();
    			Date importDate = product.getImportDate();
    			
    			Row row = sheet.createRow(curRow);
        		
    			createGeneralStringCell(generalStyle, labelId, row, 0);
    			createGeneralNumericCell(generalStyle, vendorId, row, 1);
    			createGeneralStringCell(generalStyle, albumId, row, 2);
    			createGeneralNumericCell(generalStyle, productId, row, 3);
    			createGeneralStringCell(generalStyle, upc, row, 4);
    			createGeneralStringCell(generalStyle, labelMessage, row, 5);
    			createGeneralStringCell(generalStyle, productMessage, row, 6);
    			createDateCell(dateStyle, importDate, row, 7);
        		    			
    			curRow++;
    		}
    	}
		autosizeColumns(sheet, 7);
	}

	private void writeMissingAssetsSheet(Iterable<LabelStatus> missingAssetsTable,
			Sheet sheet, CellStyle generalStyle, CellStyle dateStyle) {
		int curRow = 0;
    	Row header = sheet.createRow(curRow);
    	
    	createGeneralStringCell(generalStyle, "finetunes ID", header, 0);
    	createGeneralStringCell(generalStyle, "vendor ID", header, 1);
    	createGeneralStringCell(generalStyle, "finetunes album ID", header, 2);
    	createGeneralStringCell(generalStyle, "product ID", header, 3);
    	createGeneralStringCell(generalStyle, "UPC", header, 4);
    	createGeneralStringCell(generalStyle, "Message (Label Level)", header, 5);
    	createGeneralStringCell(generalStyle, "Message (Product Level)", header, 6);
    	createGeneralStringCell(generalStyle, "import Date", header, 7);
    	
		curRow++;
    	
    	for (LabelStatus entry : missingAssetsTable) {
    		String labelId = entry.getLabelId();
    		int vendorId = entry.getVendorId();
    		String labelMessage = entry.getMessage();
    		Collection<ImportedProduct> importedProducts = entry.getImportedProducts();
    		for (ImportedProduct product : importedProducts) {
    			
    			if (!ASSET_MISSING_ERR_MSG.equals(product.getMessage())) {
    				continue;
    			}
    			
    			String albumId = product.getReleaseId();
    			int productId = product.getProductId();
    			String upc = product.getUpc();
    			String productMessage = product.getMessage();
    			Date importDate = product.getImportDate();
    			
    			Row row = sheet.createRow(curRow);
        		
    			createGeneralStringCell(generalStyle, labelId, row, 0);
    			createGeneralNumericCell(generalStyle, vendorId, row, 1);
    			createGeneralStringCell(generalStyle, albumId, row, 2);
    			createGeneralNumericCell(generalStyle, productId, row, 3);
    			createGeneralStringCell(generalStyle, upc, row, 4);
    			createGeneralStringCell(generalStyle, labelMessage, row, 5);
    			createGeneralStringCell(generalStyle, productMessage, row, 6);
    			createDateCell(dateStyle, importDate, row, 7);
        		    			
    			curRow++;
    		}
    	}
		autosizeColumns(sheet, 7);
	}


	private void writeAssetIngestionStatusSheet(Iterable<LabelStatus> table, Sheet sheet, CellStyle generalStyle) {

		int curRow = 0;
		Row header = sheet.createRow(curRow);

		createGeneralStringCell(generalStyle, "Label ID", header, 0);
		createGeneralStringCell(generalStyle, "Ingested Products", header, 1);
		createGeneralStringCell(generalStyle, "Missing Products (deltas)", header, 2);
		createGeneralStringCell(generalStyle, "Unknown Orchard Products", header, 3);
		createGeneralStringCell(generalStyle, "Broken Products", header, 4);

		curRow++;

		for (LabelStatus status : table) {
			int vendorId = status.getVendorId();
			int ingestedProducts = 0;
			int brokenProducts = 0;
			int missingProducts = 0;
			int unknownOrchardProducts = 0;

			for (ImportedProduct product : status.getImportedProducts()) {
				String prouctStatus = product.getStatus();
				if ("Good".equals(prouctStatus)) {
					ingestedProducts++;
				} else if ("Error".equals(prouctStatus)) {
					if (ASSET_MISSING_ERR_MSG.equals(product.getMessage())) {
						missingProducts++;
					} else {
						brokenProducts++;
					}
				}
			}

			List<UnknownOrchardUpc> mappedLabelUpcs = unknownOrchardUpcRepository.findByLabelId(status.getLabelId());
			for (UnknownOrchardUpc upc : mappedLabelUpcs) {
				if (upc.getFinetunesUpc() == null) {
					unknownOrchardProducts++;
				}
			}

			Row row = sheet.createRow(curRow);

			createGeneralNumericCell(generalStyle, vendorId, row, 0);
			createGeneralNumericCell(generalStyle, ingestedProducts, row, 1);
			createGeneralNumericCell(generalStyle, missingProducts, row, 2);
			createGeneralNumericCell(generalStyle, unknownOrchardProducts, row, 3);
			createGeneralNumericCell(generalStyle, brokenProducts, row, 4);

			curRow++;
		}

		autosizeColumns(sheet, 4);

	}


	private void writeStatusToSheet(Iterable<LabelStatus> table, Sheet sheet, CellStyle generalStyle, CellStyle dateStyle) {
    	
		int curRow = 0;
    	Row header = sheet.createRow(curRow);
    	
    	createGeneralStringCell(generalStyle, "finetunes ID", header, 0);
    	createGeneralStringCell(generalStyle, "vendor ID", header, 1);
    	createGeneralStringCell(generalStyle, "label status", header, 2);
    	createGeneralStringCell(generalStyle, "update date", header, 3);
    	createGeneralStringCell(generalStyle, "message", header, 4);
    	createGeneralStringCell(generalStyle, "# successful products", header, 5);
    	createGeneralStringCell(generalStyle, "# broken products", header, 6);
    	
		curRow++;
		
    	for (LabelStatus status : table) {
    		String labelId = status.getLabelId();
    		int vendorId = status.getVendorId();
    		String labelStatus = status.getStatus();
    		Date updateDate = status.getUpdateDate();
    		String message = status.getMessage();
    		int goodProducts = 0;
    		int errorProducts = 0;
    		for (ImportedProduct product : status.getImportedProducts()) {
    			String prouctStatus = product.getStatus();
    			if ("Good".equals(prouctStatus)) {
    				goodProducts++;
    			} else if ("Error".equals(prouctStatus)) {
    				errorProducts++;
    			}
    		}
    			
    		Row row = sheet.createRow(curRow);
    		
    		createGeneralStringCell(generalStyle, labelId, row, 0);
    		createGeneralNumericCell(generalStyle, vendorId, row, 1);
    		createGeneralStringCell(generalStyle, labelStatus, row, 2);
    		createDateCell(dateStyle, updateDate, row, 3);
    		createGeneralStringCell(generalStyle, message, row, 4);
    		createGeneralNumericCell(generalStyle, goodProducts, row, 5);
    		createGeneralNumericCell(generalStyle, errorProducts, row, 6);
    		
    		curRow++;
    	}

		autosizeColumns(sheet, 6);
	}
	
	
	private CellStyle buildGeneralCellStyle(Workbook workbook) {
		Font font = workbook.createFont();
		font.setFontName("Arial");
		CellStyle generalStyle = workbook.createCellStyle();
		generalStyle.setFont(font);
		return generalStyle;
	}


	private CellStyle buildDateStyle(Workbook workbook) {
		Font font = workbook.createFont();
		font.setFontName("Arial");
		CellStyle dateStyle = workbook.createCellStyle();
		CreationHelper createHelper = workbook.getCreationHelper();
		dateStyle.setFont(font);
		dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("m/d/yy h:mm"));
		return dateStyle;
	}


	private void createDateCell(CellStyle dateStyle, Date date, Row row, int colIndex) {
		Cell updateDateCell = row.createCell(colIndex);
		updateDateCell.setCellStyle(dateStyle);
		updateDateCell.setCellValue(date);
	}


	private void createGeneralStringCell(CellStyle generalStyle, String value, Row row, int colIndex) {
		Cell labelIdCell = row.createCell(colIndex);
		labelIdCell.setCellStyle(generalStyle);
		labelIdCell.setCellValue(value);
	}


	private void createGeneralNumericCell(CellStyle generalStyle, long value, Row row, int colIndex) {
		Cell labelIdCell = row.createCell(colIndex);
		labelIdCell.setCellStyle(generalStyle);
		labelIdCell.setCellValue(value);
	}


	private void autosizeColumns(Sheet sheet, int lastColNum) {
		for (int i = 0; i <= lastColNum; i++) {
			sheet.autoSizeColumn(i);
			sheet.setColumnWidth(i, sheet.getColumnWidth(i) + COLUMN_EXTRA_WIDTH);
		}
	}
	
}
