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

import java.util.ArrayList;
import java.util.HashMap;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;
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.test.TestLogger;
import com.ftinc.si.assist.test.Tool;

public class JSDriverOnBrowser implements JSDriver {

	private WebDriver m_driver = null;

	public void quit() {
		if (m_driver != null) {
			m_driver.quit();
			m_driver = null;
		}
	}

	@Override
	public boolean load(HashMap<String, Object> map) {
		if (m_driver == null) {
			m_driver = getDriver();
		}
		if (m_driver == null) {
			TestLogger.err("Execution Failed: BROWSER not specified.");
			return false;
		}

		@SuppressWarnings("unchecked")
		ArrayList<String> flist = (ArrayList<String>)map.get("includes");
		if (flist.size() == 1) {
			//urlを読み込む。
			m_driver.get(Tool.convert2Alias(flist.get(0)));

			Wait<WebDriver> wait = new WebDriverWait(m_driver, 20);
			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 {
				wait.until(u_ec);
			} catch (Exception e) {
				TestLogger.err(flist.get(0) + " >>" + e.getMessage());
				return false;
			}
		}
		return true;
	}

	@Override
	public boolean execute(String str) {
		try {
			Object xret = ((JavascriptExecutor)m_driver).executeScript(str);
			if (str.startsWith("if")) {
				//評価式の場合
				if (xret == null || xret.toString().equals("false")) {
					return false;
				}
			}
		} catch(Exception e) {
			TestLogger.err("Execution Failed:" + str + " >>" + e.getMessage());
			return false;
		}
		return true;
	}

	//System.propertiesにブラウザが指定された時、対応するドライバを取得する。
	//Pluginの編集で、System.getProperty("webdriver.chrome.driver")でchromedriver.exeへのPathが取れるようにしておく。
	private WebDriver getDriver() {
		WebDriver drv = null;
		String bname = System.getProperty("webtest.browser").toLowerCase(); //$NON-NLS-1$

		try {
			//単独
			if (bname.equals("firefox")) { //$NON-NLS-1$
				drv = new FirefoxDriver();
			} else if (bname.equals("ie")) { //$NON-NLS-1$
				InternetExplorerOptions ieCap = new InternetExplorerOptions();
				ieCap.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
				drv = new InternetExplorerDriver(ieCap);
			} else if (bname.equals("chrome")) { //$NON-NLS-1$
				ChromeOptions chromeOptions = new ChromeOptions();
			    chromeOptions.addArguments("--headless");
				drv = new ChromeDriver(chromeOptions);
			} else if (bname.equals("edge")) { //$NON-NLS-1$
				drv = new EdgeDriver();
			}
		} catch (Throwable e) {
			Tool.alertMSG(null, "Failed to connect browser=<" + bname + ">\n" + e.getMessage());
			if (drv != null) {
				drv.quit();
			}
			return null;
		}

		return drv;
	}

	@Override
	public void reset() {
		//オリジナルは残す。
		m_driver.get("about:blank");
	}
}
