package com.saucelabs.common;

import com.saucelabs.saucerest.DataCenter;
import com.saucelabs.saucerest.SauceREST;
import io.restassured.path.json.JsonPath;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.SessionId;

import java.net.MalformedURLException;
import java.net.URL;


public class SauceHelperAcceptanceTest
{
    private String username = System.getenv("SAUCE_USERNAME");
    private String accesskey = System.getenv("SAUCE_ACCESS_KEY");
    String SAUCE_REMOTE_URL = "https://ondemand.saucelabs.com/wd/hub";
    private WebDriver driver;

    @Rule
    public TestName testName = new TestName();

    @Test
    public void shouldSetTestStatusToPassed() throws MalformedURLException {
        ChromeOptions caps = getChromeOptions();
        MutableCapabilities sauceOptions = getMutableCapabilities();

        caps.setCapability("sauce:options", sauceOptions);
        driver = new RemoteWebDriver(new URL(SAUCE_REMOTE_URL), caps);
        SessionId sessionId = ((RemoteWebDriver) driver).getSessionId();

        driver.navigate().to("https://www.saucedemo.com");
        SauceHelper sauceHelper = new SauceHelper(driver);
        sauceHelper.setTestStatus("passed");
        driver.quit();

        SauceREST sauceRest = new SauceREST(username, accesskey, DataCenter.US);
        String jobInfo = sauceRest.getJobInfo(sessionId.toString());
        Boolean isPassed = checkIfTestPassed(jobInfo);
        Assert.assertEquals(true, isPassed);
    }
    @Test
    public void shouldSetTestStatusToPassedWithSeleniumJSExecutor() throws MalformedURLException {
        ChromeOptions caps = getChromeOptions();
        MutableCapabilities sauceOptions = getMutableCapabilities();

        caps.setCapability("sauce:options", sauceOptions);
        driver = new RemoteWebDriver(new URL(SAUCE_REMOTE_URL), caps);
        SessionId sessionId = ((RemoteWebDriver) driver).getSessionId();

        driver.navigate().to("https://www.saucedemo.com");
        ((JavascriptExecutor)driver).executeScript("sauce:job-result=passed");
        driver.quit();

        SauceREST sauceRest = new SauceREST(username, accesskey, DataCenter.US);
        String jobInfo = sauceRest.getJobInfo(sessionId.toString());
        Boolean isPassed = checkIfTestPassed(jobInfo);
        Assert.assertEquals(true, isPassed);
    }

    @After
    public void afterTest()
    {
        if(driver != null){
            driver.quit();
        }
    }

    private MutableCapabilities getMutableCapabilities() {
        MutableCapabilities sauceOptions;
        sauceOptions = new MutableCapabilities();
        sauceOptions.setCapability("username", username);
        sauceOptions.setCapability("accessKey", accesskey);
        sauceOptions.setCapability("seleniumVersion", "3.141.59");
        sauceOptions.setCapability("name", getTestName());
        return sauceOptions;
    }

    private ChromeOptions getChromeOptions() {
        ChromeOptions caps;
        caps = new ChromeOptions();
        caps.setCapability("version", "72.0");
        caps.setCapability("platform", "Windows 10");
        caps.setExperimentalOption("w3c", true);
        return caps;
    }
    private Boolean checkIfTestPassed(String jobInfo) {
        Boolean isPassed;
        try
        {
            isPassed = JsonPath.from(jobInfo).getBoolean("passed");
        }
        catch(NullPointerException e)
        {
            isPassed = false;
        }
        return isPassed;
    }
    public String getTestName()
    {
        return this.getClass().getSimpleName() + " " + testName.getMethodName();
    }
    //TODO need a test that doesn't set the test status with JS executor, in which case "passed" should be null
}

@@ -172,84 +172,9 @@
 nit.
-After;%0Aimport org.junit.Assert;%0Aimport org.junit.Rule;%0Aimport org.junit.Test
+*
 ;%0Aim
@@ -815,16 +815,41 @@
  driver;
+%0A    SessionId sessionId;
 %0A%0A    @R
@@ -901,28 +901,30 @@
 me();%0A%0A    @
-Test
+Before
 %0A    public 
@@ -932,35 +932,25 @@
 oid 
-shouldSetTestStatusToPassed
+runBeforeEachTest
 () t
@@ -1089,33 +1089,32 @@
 Capabilities();%0A
-%0A
         caps.set
@@ -1231,34 +1231,24 @@
 s);%0A        
-SessionId 
 sessionId = 
@@ -1342,32 +1342,97 @@
 aucedemo.com%22);%0A
+    %7D%0A%0A    @Test%0A    public void shouldSetTestStatusToPassed()%7B%0A%0A
         SauceHel
@@ -1880,421 +1880,9 @@
 or()
- throws MalformedURLException %7B%0A        ChromeOptions caps = getChromeOptions();%0A        MutableCapabilities sauceOptions = getMutableCapabilities();%0A%0A        caps.setCapability(%22sauce:options%22, sauceOptions);%0A        driver = new RemoteWebDriver(new URL(SAUCE_REMOTE_URL), caps);%0A        SessionId sessionId = ((RemoteWebDriver) driver).getSessionId();%0A%0A        driver.navigate().to(%22https://www.saucedemo.com%22);
+%7B
 %0A   

remove duplication for test setup into a Before annotation