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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.ftinc.si.assist.run.Messages;
import com.ftinc.si.assist.test.Tool;

public class LoadURL extends PageAction {

	@Override
	protected void doCore(WebDriver drv, WebElement elm) {
		String t_url = (String)arg_map.get("url"); //$NON-NLS-1$
		if (t_url == null) {
			return;
		}

		//別名に変える必要があるなら置き換える。
		t_url = Tool.convert2Alias(t_url); //$NON-NLS-1$
		if (t_url.length() == 0) {
			//別名で空文字になった場合、loadするなということ。
			return;
		}

		//Basic認証情報があれば追加
		String t_auth = (String)arg_map.get("auth"); //$NON-NLS-1$
		if (t_auth != null && t_auth.length() > 0 && t_auth.matches("^\\w+:\\w+@$")) { //$NON-NLS-1$
			//認証情報が書式通りに指定されている。
			Pattern t_pat = Pattern.compile("^(https?://)(.+)$"); //$NON-NLS-1$
			Matcher t_m = t_pat.matcher(t_url);
			if (t_m.find()) {
				t_url = t_url.replaceFirst(Pattern.quote(t_url), "$1" + Matcher.quoteReplacement(t_auth) + "$2"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			Tool.logIfDebug(null, "Trying to add auth=" + t_auth + " to URL.");
		}

//		final String old_title = drv.getTitle();
		drv.get(t_url);

		Wait<WebDriver> wait = new WebDriverWait(drv, getTimeout());
/*		ExpectedCondition<Boolean> t_ec = new ExpectedCondition<Boolean>() {
			public Boolean apply(WebDriver drv) {
				String n_title = drv.getTitle();
				if (old_title == null) {
					if (n_title != null && n_title.length() > 0) {
						return true;
					}
				} else if (!old_title.equals(n_title)) {
					return true;
				}
				return null;
			}
		};*/
		ExpectedCondition<Boolean> u_ec = new ExpectedCondition<Boolean>() {
			public Boolean apply(WebDriver drv) {
				Object t_state = ((JavascriptExecutor)drv).executeScript("return document.readyState");
				if (t_state.equals("complete")) {
					return true;
				}
				return false;
			}
		};


		try {
			//Titleが変わるまで待つ。
//			wait.until(t_ec);

			//読込が終わるまで待つ。
			wait.until(u_ec);
		} catch (Exception e) {
			throw new TimeoutException(Messages.getString("LoadURL.1") + e.getMessage()); //$NON-NLS-1$
		}


	}


	//WebElementGetterのTarget欄の値を指定する。
	protected String getTarget() {
		return (String)arg_map.get("url"); //$NON-NLS-1$
	}

	//以下、Assertと二重の書き込みになるが自動的に整合性は保たれる。
	//WebElementGetterのArgument欄の値を指定する。
	protected ArrayList<String> getLabelAndParams() {
		ArrayList<String> t_list2 = new ArrayList<String>();

		//最初はlabel
		t_list2.add(Messages.getString("LoadURL.0")); //$NON-NLS-1$
		Object t_auth = arg_map.get("auth"); //$NON-NLS-1$
		if (t_auth != null) {
			t_list2.add(t_auth.toString());
		} else {
			t_list2.add(""); //$NON-NLS-1$
		}
		t_list2.add("user:password@"); //$NON-NLS-1$
		return t_list2;
	}

	//path情報を持つアクションかどうか
	protected boolean hasPath() {
		return false;
	}


	//このPageActionが対象とするWebElementとそのXpathを取得する。
	protected boolean getFocussingElements(WebDriver drv, ArrayList<WebElement> el_list, ArrayList<String> xp_list, String xpaths) {
		if (drv != null) {
			//URLを読み込む
			arg_map.put("url", drv.getCurrentUrl()); //$NON-NLS-1$
		}

		return true;//WebElementGetterを開くサイン
	}


	//PageActionEditorの第二列に書き込む内容を合成する。
	protected String getJsonElement(String target, String arg) {
		if (target != null && target.length() > 0) {
			arg_map = new HashMap<String, Object>();

			//targetはurlそのものなので。
			arg_map.put("url", target); //$NON-NLS-1$
			if (arg.length() > 0) {
				arg_map.put("auth", arg); //$NON-NLS-1$
			}
		}
		return super.getJsonElement(null,  null);
	}

}
