package com.ftinc.si.assist.test.web;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import javassist.CannotCompileException;
import javassist.NotFoundException;

import com.ftinc.si.assist.run.Messages;
import com.ftinc.si.assist.run.VCentral;
import com.ftinc.si.assist.test.AssertRecord;
import com.ftinc.si.assist.test.Fson.NotSupportedClassException;
import com.ftinc.si.assist.test.TestCommandRecord;
import com.ftinc.si.assist.test.Tool;

public class WebTestCommandRecord extends TestCommandRecord {

	private PagePlayer cur_player;
	
	public WebTestCommandRecord(int i) {
		super(i);
	}

	//現在のPagePlayerを記録する。
	public Object getTObject(Integer i) throws SecurityException, IllegalArgumentException, ClassNotFoundException, 
							InstantiationException, IllegalAccessException, NoSuchFieldException, CannotCompileException, IOException, 
							NotFoundException, NoSuchMethodException, InvocationTargetException, ParseException, NotSupportedClassException {
		Object t_obj = super.getTObject(i);
		if (i == 0) {
			cur_player = (PagePlayer)t_obj;
		}
		return t_obj;
	}
	
	//デフォルトはtrue。詳細はPlayerに聞く。
	public boolean isAutomatic() {
		if (cur_player != null) {
			return cur_player.isAutomatic();
		}
		return true;
	}

	//ログのclassnameに相当する。画面のパラメータ名を返すようにする。
	public String getName4Log() {
		if (cur_player != null) {
			return cur_player.paramName();
		}
		return Integer.toString(id);
	}
	
	private ArrayList<String> m_asserts;
	
	//DBに入っていれば、それで構成する。
	public AssertRecord getAssert() throws ProcessException {
		//外部プロセスが規定されていたら実行する。
		postExec();
		
		AssertRecord t_ast = Tool._db().getAssert(id);

		WebAssertRecord t_rec = new WebAssertRecord(0);
		t_rec.id = id;
		t_rec.targetObj = "_ASSERTABLES";//nullを回避するため適当な文字列を入れる。Assertの最初の判定を通過するために必要。 //$NON-NLS-1$
		if (t_ast != null) {
			t_rec.criteriaType = t_ast.criteriaType;
			t_rec.criteriaRex = t_ast.criteriaRex;
			t_rec.description = t_ast.description;
		}
		if ("[]".equals(t_rec.criteriaRex) && cur_player != null) { //$NON-NLS-1$
			//正規表現のリストが空の場合（マクロの再利用など）、Playerから取得する。
			m_asserts = cur_player.getAssertRegs();
			t_rec.criteriaRex = Tool.getJSONfromObject(m_asserts);
		}
		
		return t_rec;
	}
	
	//Web用のAssert派生クラス
	class WebAssertRecord extends AssertRecord {
		public WebAssertRecord(int i) {
			super(i);
		}
		
		//Assertのレコードがすべて入力されたかどうか。
		public boolean isCompleted() {
			return true;
		}

		protected ArrayList<Object> getResultString(TestCommandRecord curCmd) throws SecurityException, 
				IllegalArgumentException, CannotCompileException, InstantiationException, IllegalAccessException, ClassNotFoundException, 
				NotFoundException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException, ParseException {
			
			Object t_obj = Tool.instance_table.get(Integer.toString(id) + "$_"); //$NON-NLS-1$
			if(t_obj == null) {
				return null;
			}
			@SuppressWarnings("unchecked")
			ArrayList<Object> t_result = (ArrayList<Object>)t_obj;

			@SuppressWarnings("unchecked")
			HashMap<String, String> t_map = (HashMap<String, String>)VCentral.getValue("_ASSERTABLES"); //$NON-NLS-1$
				//t_mapはTestCommand実行のたびに初期化されるので、このAssert専用となっている。。

			if (t_map != null) {
				//DBの状態確認がある場合。
				//dbtestやobjtestがある場合。判定の正規表現はgetValue()、値取得はgetKey()。
				//カラム指定が*でなければ、指定カラムの値の文字列表現がt_resultに追加される。
				//※カラム指定は、getKey()の最後尾である。
				for (Entry<String, String> entry: t_map.entrySet()) {
					m_asserts.add(entry.getValue());
					t_result.add(VCentral.getValue(entry.getKey()));
				}
				criteriaRex = Tool.getJSONfromObject(m_asserts);
			}
			
			if ((!"[]".equals(criteriaRex) && t_result.size() > 0) || ("[]".equals(criteriaRex) && t_result.size() == 0)) {
				return t_result;
			}
			throw new NotFoundException(Messages.getString("WebTestCommandRecord.4")); //$NON-NLS-1$
		}

	}
}
