package jp.sourceforge.cfneo.at4ie.api.impl;

import jp.sourceforge.cfneo.at4ie.api.AT4IERuntimeException;
import jp.sourceforge.cfneo.at4ie.api.FileValidator;
import jp.sourceforge.cfneo.at4ie.api.TestRunner;
import jp.sourceforge.cfneo.at4ie.impl.csv.CsvTestRunner;
import jp.sourceforge.cfneo.at4ie.impl.csv.CsvValidator;
import jp.sourceforge.cfneo.at4ie.impl.xls.ExcelTestRunner;
import jp.sourceforge.cfneo.at4ie.impl.xls.ExcelValidator;
import jp.sourceforge.cfneo.at4ie.utils.PathUtil;

import org.apache.log4j.Logger;

/**
 * テストに関する具象クラスをまとめて生成する為のファクトリ。<br />
 * FileValidator、TestCaseを一括して生成する為のクラス。
 * @author imaitakafumi
 *
 */
public class TestFactory {

	/**
	 * ファイルの種類を判別する為のEnum。
	 * @author imaitakafumi
	 *
	 */
	enum FileType {
		EXCEL(".xls"), CSV(".csv"), JSEL(".html");
		private String value;
		private FileType(String value) {
			this.value = value;
		}
		public String toString() {
			return this.value;
		}
		public static FileType get(String value) {
			FileType[] items = FileType.values();
			for (FileType item: items) {
				if (item.toString().equals(value))
					return item;
			}
			return null;
		}
	}

	Logger logger = Logger.getLogger(TestFactory.class);

	private String filepath;
	private FileType fileType;

	private FileValidator validator;
	private TestRunner testRunner;

	/**
	 * コンストラクタ。
	 * @param filepath
	 */
	public TestFactory(String filepath) {
		if (filepath != null) {
			logger.debug("TestFactory#TestFactory filepath=" + filepath);
			this.filepath = filepath;
			this.fileType = FileType.get(PathUtil.getFileExtension(this.filepath));
			logger.debug("TestFactory#TestFactory this.fileType=" + this.fileType);
			this.createTest();
		}
	}

	/**
	 * ファイルの種類ごとにファクトリ・メソッドを使い分ける。
	 */
	protected void createTest() {
		switch (this.fileType) {
		case CSV:
			this.createForCsv();
			break;
		case EXCEL:
			this.createForExcel();
			break;
		default:
			this.createForCsv();
			break;
		}
		try {
			this.validator.validate(this.filepath);
		} catch (Exception e) {
			throw new AT4IERuntimeException(e);
		}
	}

	/**
	 * CSVファイルでテストケースを受け取る場合のテストのファクトリ・メソッド。
	 */
	protected void createForCsv() {
		logger.debug("TestFactory#createForCsv" );
		this.testRunner = new CsvTestRunner(this.filepath);
		this.validator = new CsvValidator(this.testRunner.getContext());
	}

	/**
	 * Excelファイルでテストケースを受け取る場合のテストのファクトリ・メソッド。
	 */
	protected void createForExcel() {
		logger.debug("TestFactory#createForExcel" );
		try {
			this.testRunner = new ExcelTestRunner(this.filepath);
			this.validator = new ExcelValidator();
		} catch (Exception e) {
			throw new AT4IERuntimeException(e);
		}
	}

	protected void setValidator(FileValidator validator) {
		this.validator = validator;
	}
	protected void setTestRunner(TestRunner testRunner) {
		this.testRunner = testRunner;
	}
	public TestRunner getTestRunner() {
		return this.testRunner;
	}
	/**
	 * TestFactoryの内容を文字列化。
	 */
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("*** TestFactory ***");
		sb.append("\n filepath=");
		sb.append(this.filepath);
		sb.append("\n fileType=");
		sb.append(this.fileType.toString());
		sb.append("\n validator=");
		sb.append(this.validator.getClass().getName());
		sb.append("\n testRunner=");
		sb.append(this.testRunner.getClass().getName());
		return sb.toString();
	}

}
