package com.eactive.eai.transformer.dao.excel;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.TreeMap;

import com.eactive.eai.common.util.Logger;
import com.eactive.eai.transformer.dao.TransformerDaoException;

public abstract class BaseExcelDao<K, V> {
	protected static Logger logger = Logger.getLogger("transformer.dao");

	private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");

	private String baseDir;

	protected BaseExcelDao(String baseDir) {
		String rootDir = System.getProperty("transformer.rule.dir", "");
		if ("".equals(rootDir)) {
			rootDir = ".";
		}
		this.baseDir = rootDir + File.separator + baseDir;
	}

	public Map<K, V> load() {
		if (logger.isInfoEnabled()) {
			logger.info(getClass().getSimpleName() + " | loading dir - " + baseDir);
		}

		try {
			Map<K, V> map = new TreeMap<>();

			File dir = new File(baseDir);
			File[] files = dir.listFiles();

			if (files != null) {
				for (int i = 0; i < files.length; i++) {
					if (files[i].isFile() && files[i].getName().toLowerCase().endsWith(".xls")) {
						map.putAll(loadExcelFile(files[i].getPath()));
					}
				}
			}

			return map;
		} catch (Exception e) {
			throw new TransformerDaoException(e.getMessage(), e);
		}
	}

	protected Map<K, V> loadExcelFile(String fileName) {
		File file = new File(fileName);

		if (file.getName().startsWith("-")) {
			return new TreeMap<>();
		}
		try (InputStream in = new BufferedInputStream(new FileInputStream(fileName))) {
			/**
			 * find sheets
			 */
			Sheet[] sheets = null;
			sheets = ExcelSheet.getExcelSheets(in);
			/**
			 * type & version
			 */
			String type = sheets[0].getCellString(2, 2);
			String version = sheets[0].getCellString(3, 2);
			boolean overwrite = sheets[0].isEquals(6, 4, "O");

			if (logger.isDebugEnabled()) {
				String msg = String.format("    - %-25s | %1s, %-10s | %s", "loading excel - " + type, version,
						(overwrite ? "overwrite" : ""), file.getName());
				logger.debug(msg);
			}
			return loadSheets(sheets);
		} catch (Exception e) {
			throw new TransformerDaoException("error when load excel file '" + fileName + "'", e);
		}
	}

	public String getCurrentDateTime() {
		return DATE_FORMAT.format(ZonedDateTime.now());
	}

	abstract protected Map<K, V> loadSheets(Sheet[] sheets) throws Exception;

	abstract protected Map<K, V> removeSheets(Sheet[] sheets) throws Exception;

	abstract protected Map<K, V> parse(Sheet[] sheets) throws Exception;
}
