package org.musetest.selenium.steps;

import org.musetest.core.*;
import org.musetest.core.context.*;
import org.musetest.core.resource.*;
import org.musetest.core.step.*;
import org.musetest.core.step.descriptor.*;
import org.musetest.core.steptest.*;
import org.musetest.core.values.*;
import org.musetest.core.values.descriptor.*;
import org.musetest.core.values.strings.*;
import org.musetest.selenium.*;
import org.openqa.selenium.*;
import org.slf4j.*;

/**
 * @author Christopher L Merrill (see LICENSE.txt for license details)
 */
@MuseTypeId("open-browser")
@MuseStepName("Open a browser")
@MuseInlineEditString("open {browser} using {provider}")
@MuseStepIcon("glyph:FontAwesome:GLOBE")
@MuseStepTypeGroup("Selenium")
@MuseStepShortDescription("Open a new browser session")
@MuseStepLongDescription("Opens a browser using the 'browser' and 'provider' sources. The 'browser' should resolve to a SeleniumBrowserCapabilities object. Likewise, the 'provider' should resolve to a WebDriverProviderConfiguration, which is used to instantiate a WebDriver using the supplied capabilities.")
@MuseSubsourceDescriptor(displayName = "Browser", description = "The capabilities of browser to open (expects a project resource of type SeleniumBrowserCapabilities)", type = SubsourceDescriptor.Type.Named, name = OpenBrowser.BROWSER_PARAM)
@MuseSubsourceDescriptor(displayName = "Provider", description = "The browser provider to use (expects a project resource of type WebDriverProviderConfiguration)", type = SubsourceDescriptor.Type.Named, name = OpenBrowser.PROVIDER_PARAM)
public class OpenBrowser extends BaseStep
    {
    @SuppressWarnings("unused") // called via reflection
    public OpenBrowser(StepConfiguration config, MuseProject project) throws MuseInstantiationException
        {
        super(config);
        _project = project;
        _browser = getValueSource(config, BROWSER_PARAM, true, project);
        _provider = getValueSource(config, PROVIDER_PARAM, true, project);
        }

    @Override
    public StepExecutionResult executeImplementation(StepExecutionContext context) throws MuseExecutionError
        {
        // find the provider
        WebDriverProviderConfiguration provider = getValue(_provider, context, false, WebDriverProviderConfiguration.class);
        final StepExpressionContext expression_context = new StepExpressionContext(_project, getConfiguration());
        if (provider == null)
            {
            ValueSourceConfiguration provider_config = getConfiguration().getSource(PROVIDER_PARAM);
            throw new StepConfigurationError("Unable to locate WebdriverProvider from source: " + context.getProject().getValueSourceDescriptors().get(provider_config).getInstanceDescription(provider_config, expression_context));
            }

        SeleniumBrowserCapabilities capabilities = getValue(_browser, context, false, SeleniumBrowserCapabilities.class);
        if (capabilities == null)
            {
            ValueSourceConfiguration browser_config = getConfiguration().getSource(PROVIDER_PARAM);
            throw new StepConfigurationError("Unable to locate SeleniumBrowserCapabilities from source: " + context.getProject().getValueSourceDescriptors().get(browser_config).getInstanceDescription(browser_config, expression_context));
            }

        WebDriver driver = provider.getDriver(capabilities, context);
        if (driver == null)
            {
            ValueSourceConfiguration provider_config = getConfiguration().getSource(PROVIDER_PARAM);
            throw new StepConfigurationError(String.format("The WebdriverProvider (%s) was not able to provide a browser matching the specified capabilities (%s).", context.getProject().getValueSourceDescriptors().get(provider_config).getInstanceDescription(provider_config, expression_context), capabilities.toDesiredCapabilities().toString()));
            }

        BrowserStepExecutionContext.putDriver(driver, context);

        context.registerShuttable(() ->
            {
            try
                {
                driver.quit();
                }
            catch (Exception e)
                {
                LOG.error("Exception encountered while cleaning up the driver", e);
                }
            });

        return new BasicStepExecutionResult(StepExecutionStatus.COMPLETE);
        }

    private final MuseValueSource _browser;
    private final MuseValueSource _provider;
    private final MuseProject _project;

    public final static String BROWSER_PARAM = "browser";
    public final static String PROVIDER_PARAM = "provider";

    public final static String TYPE_ID = OpenBrowser.class.getAnnotation(MuseTypeId.class).value();

    private final static Logger LOG = LoggerFactory.getLogger(OpenBrowser.class);
    }



@@ -1565,16 +1565,233 @@
 _PARAM)%0A
+@MuseSubsourceDescriptor(displayName = %22Close on exit%22, description = %22If true, the browser will automatically be closed when the task ends.%22, type = SubsourceDescriptor.Type.Named, name = OpenBrowser.PROVIDER_PARAM)%0A
 public c
@@ -2192,32 +2192,110 @@
 true, project);%0A
+        _autoclose = getValueSource(config, AUTOCLOSE_PARAM, false, project);%0A
         %7D%0A%0A    @
@@ -4239,24 +4239,137 @@
  context);%0A%0A
+        Boolean close = getValue(_autoclose, context, Boolean.class, true);%0A        if (close)%0A            %7B%0A    
         cont
@@ -4400,34 +4400,42 @@
  -%3E%0A            
+   
+ 
 %7B%0A
+    
             try%0A
@@ -4442,32 +4442,36 @@
                 
+    
 %7B%0A              
@@ -4472,16 +4472,20 @@
         
+ 
+   
 driver.q
@@ -4499,34 +4499,42 @@
                 
-%7D%0A
+    %7D%0A    
             catc
@@ -4557,34 +4557,42 @@
                 
-%7B%0A
+    %7B%0A    
                 
@@ -4667,34 +4667,42 @@
                 
+  
-%7D%0A
+  %7D%0A    
             %7D);%0A
@@ -4700,16 +4700,30 @@
      %7D);
+%0A            %7D
 %0A%0A      
@@ -4887,24 +4887,70 @@
  _provider;%0A
+    private final MuseValueSource _autoclose;%0A
     private 
@@ -5095,16 +5095,79 @@
 ovider%22;
+%0A    private final static String AUTOCLOSE_PARAM = %22autoclose%22;
 %0A%0A    pu

ENHANCE - add autoclose parameter to OpenBrowser step so that the browser may remain open after task completes