package com.saucelabs.remotedriver;

import com.saucelabs.common.SauceApi;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.safari.SafariOptions;

import java.net.MalformedURLException;

public class SauceSession {
	static String sauceSeleniumServer = "https://ondemand.saucelabs.com/wd/hub";

	static String SAUCE_USERNAME = System.getenv("SAUCE_USERNAME");
	static String SAUCE_ACCESS_KEY = System.getenv("SAUCE_ACCESS_KEY");
    public SauceApi test;

    //todo there is some weird bug when this is set to Linux, the session can't be started
	String operatingSystem = "Windows 10";
	String browserName = "Chrome";
	String testName;
	Boolean useSauce = true;
    String sauceOptionsTag = "sauce:options";

	public String seleniumServer;

	ChromeOptions chromeOptions;
	FirefoxOptions firefoxOptions;
	MutableCapabilities sauceOptions;
	String browserVersion = "latest";

	public MutableCapabilities capabilities;
    private RemoteDriverInterface remoteDriverManager;
    private WebDriver webDriver;
    private SafariOptions safariOptions;
    private EdgeOptions edgeOptions;
    private InternetExplorerOptions ieOptions;

    public SauceSession(){
        capabilities = new MutableCapabilities();
        remoteDriverManager = new ConcreteRemoteDriverManager();
    }

    public SauceSession(RemoteDriverInterface remoteManager) {
        remoteDriverManager = remoteManager;
        capabilities = new MutableCapabilities();
    }

    public SauceSession start() throws MalformedURLException
	{
        seleniumServer = getSeleniumServer();
        capabilities = getCapabilities();
        webDriver = remoteDriverManager.getRemoteWebDriver(seleniumServer, capabilities);
        test = new SauceApi(webDriver);
        return this;
	}
    public String getSeleniumServer() {
        if (seleniumServer == null)
        {
            seleniumServer = sauceSeleniumServer;
        }
        return seleniumServer;
    }
    public MutableCapabilities getCapabilities() {
        sauceOptions = getSauceOptions();
        setBrowserOptions(browserName);

        capabilities.setCapability(sauceOptionsTag, sauceOptions);
        capabilities.setCapability(CapabilityType.BROWSER_NAME, browserName);
        capabilities.setCapability(CapabilityType.PLATFORM_NAME, operatingSystem);
        capabilities.setCapability(CapabilityType.BROWSER_VERSION, browserVersion);

        return capabilities;
    }

    public MutableCapabilities getSauceOptions()
    {
        if (useSauce)
        {
            seleniumServer = sauceSeleniumServer;

            sauceOptions = new MutableCapabilities();
            sauceOptions.setCapability("username", SAUCE_USERNAME);
            sauceOptions.setCapability("accessKey", SAUCE_ACCESS_KEY);
            sauceOptions.setCapability("seleniumVersion", "3.141.59");

            if (testName != null)
            {
                sauceOptions.setCapability("name", testName);
            }
        }

        return sauceOptions;
    }
    //TODO this needs to be moved to it's own class because it keeps changing
    public void setBrowserOptions(String browserName)
    {
        if (browserName.equalsIgnoreCase("Chrome"))
        {
            withChrome();
            capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
        }
        else if (browserName.equalsIgnoreCase("Firefox"))
        {
            withFirefox();
            capabilities.setCapability(FirefoxOptions.FIREFOX_OPTIONS, firefoxOptions);
        }
        else if(browserName.equalsIgnoreCase("Safari"))
        {
            capabilities.setCapability(SafariOptions.CAPABILITY, safariOptions);
        }
        else if(browserName.equalsIgnoreCase("Edge"))
        {
            withEdge();
            capabilities.setCapability("Edge", edgeOptions);
        }
        else if(browserName.equalsIgnoreCase("IE"))
        {
            withIE();
            capabilities.setCapability("se:ieOptions", ieOptions);
        }
        else {
            //TODO why is this so annoying??
            //throw new NoSuchBrowserExistsException();
        }
    }

	public SauceSession withChrome()
	{
	    chromeOptions = new ChromeOptions();
		chromeOptions.setExperimentalOption("w3c", true);
		browserName = "Chrome";
		return this;
	}

	public SauceSession withFirefox()
	{
		firefoxOptions = new FirefoxOptions();
		browserName = "Firefox";

		return this;
	}

    public RemoteDriverInterface getDriverManager() {
        return remoteDriverManager;
    }


    public MutableCapabilities getSauceOptionsCapability(){
        return ((MutableCapabilities) capabilities.getCapability(sauceOptionsTag));
    }



    public WebDriver getDriver() {
        return webDriver;
    }

    //TODO How do we want to handle this?
    //1. withMacOsMojave(OperatingSystem.MacOs1014), aka, force the user to pass in a mac version
    //2. throw an exception for withMacOsMojave() used without withMac();
    //3. this is the method I chose below: withMacOsMojave(String browserVersion)
    public SauceSession withMacOsMojave() {
        operatingSystem = "macOS 10.14";
        browserName = "Safari";
        safariOptions = new SafariOptions();
        return this;
    }
    public SauceSession withBrowserVersion(String browserVersion){
        this.browserVersion = browserVersion;
        return this;
    }

    public SauceSession withEdge() {
        this.browserName = "Edge";
        edgeOptions = new EdgeOptions();
        return this;
    }

    public SauceSession withIE() {
        this.browserName = "IE";
        ieOptions = new InternetExplorerOptions();
        return this;
    }

    public SauceSession withPlatform(String operatingSystem) {
        this.operatingSystem = operatingSystem;
        return this;
    }

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

    public SauceSession withMacOsHighSierra()
    {
        this.operatingSystem = "macOS 10.13";
        browserName = "Safari";
        safariOptions = new SafariOptions();
        return this;
    }
}

@@ -3500,34 +3500,8 @@
   %7B%0A
-            withChrome();%0A
     
@@ -3569,32 +3569,32 @@
 chromeOptions);%0A
+
         %7D%0A      
@@ -3659,35 +3659,8 @@
   %7B%0A
-            withFirefox();%0A
     
@@ -3811,32 +3811,81 @@
 ri%22))%0A        %7B%0A
+            safariOptions = new SafariOptions();%0A
             capa
@@ -4027,32 +4027,8 @@
   %7B%0A
-            withEdge();%0A
     
@@ -4160,30 +4160,8 @@
   %7B%0A
-            withIE();%0A
     
@@ -5412,43 +5412,155 @@
     
-safariOptions = new SafariOptions()
+return this;%0A    %7D%0A    public SauceSession withMacOsHighSierra()%0A    %7B%0A        this.operatingSystem = %22macOS 10.13%22;%0A        browserName = %22Safari%22
 ;%0A  
@@ -6203,32 +6203,32 @@
 Driver != null)%0A
+
             webD
@@ -6250,210 +6250,7 @@
    %7D
-%0A%0A    public SauceSession withMacOsHighSierra()%0A    %7B%0A        this.operatingSystem = %22macOS 10.13%22;%0A        browserName = %22Safari%22;%0A        safariOptions = new SafariOptions();%0A        return this;%0A    %7D
 %0A%7D%0A

fix a bug with the system that was resetting all of the operating systems in the getBrowserCaps()