package org.jbehave.web.selenium;

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

import org.openqa.selenium.OutputType;
import org.openqa.selenium.Platform;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.DriverCommand;
import org.openqa.selenium.remote.RemoteWebDriver;

/**
 * <p>
 * Provides a {@link RemoteWebDriver} that connects to a URL specified by system
 * property "REMOTE_WEBDRIVER_URL" and allows to take screenshots.
 * </p>
 * <p>
 * The default {@link DesiredCapabilities}, specified by
 * {@link #defaultDesiredCapabilities()}, are for Windows Firefox 3.6 allowing
 * screenshots.
 * </p>
 */
public class RemoteWebDriverProvider extends DelegatingWebDriverProvider {

    protected DesiredCapabilities desiredCapabilities;
    private boolean verbose = false;

    public RemoteWebDriverProvider() {
        this(defaultDesiredCapabilities());
    }

    public static DesiredCapabilities defaultDesiredCapabilities() {
        DesiredCapabilities desiredCapabilities = DesiredCapabilities.firefox();
        desiredCapabilities.setVersion("3.6.");
        desiredCapabilities.setPlatform(Platform.WINDOWS);
        desiredCapabilities.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
        return desiredCapabilities;
    }

    public RemoteWebDriverProvider(DesiredCapabilities desiredCapabilities) {
        this.desiredCapabilities = desiredCapabilities;
    }

    public void initialize() {
        URL url = null;
        WebDriver remoteWebDriver;
        try {
            url = createRemoteURL();
            remoteWebDriver = new ScreenshootingRemoteWebDriver(url, desiredCapabilities);
        } catch (Throwable e) {
            if (verbose) {
                e.printStackTrace(System.err);
            }
            throw new UnsupportedOperationException("Connecting to remote URL '" + url + "' failed: " + e.getMessage(),
                    e);
        }
        // Augmenter does not work. Resulting WebDriver is good for exclusive
        // screenshooting, but not normal operation as 'session is null'
        // remoteWebDriver = new Augmenter().augment(remoteWebDriver);
        // should allow instanceof TakesScreenshot
        delegate.set(remoteWebDriver);
    }

    public URL createRemoteURL() throws MalformedURLException {
        String url = System.getProperty("REMOTE_WEBDRIVER_URL");
        if (url == null) {
            throw new UnsupportedOperationException("REMOTE_WEBDRIVER_URL property not specified");
        }
        return new URL(url);
    }

    static class ScreenshootingRemoteWebDriver extends RemoteWebDriver implements TakesScreenshot {

        public ScreenshootingRemoteWebDriver(URL remoteURL, DesiredCapabilities desiredCapabilities) {
            super(remoteURL, desiredCapabilities);
        }

        public <X> X getScreenshotAs(OutputType<X> target) throws WebDriverException {
            // Paul: Copied from FirefoxDriver.......
            // Get the screenshot as base64.
            String base64 = execute(DriverCommand.SCREENSHOT).getValue().toString();
            // ... and convert it.
            return target.convertFromBase64Png(base64);
        }
    }

    public void useVerbosity(boolean verbose) {
        this.verbose = verbose;
    }
}

@@ -1903,32 +1903,136 @@
  if (verbose) %7B%0A
+                System.err.println(%22*********** Remote WebDriver Initialization Failure ************%22);%0A
                 
@@ -2502,16 +2502,86 @@
 reenshot
+.%0A        // To take out when this is fixed in Selenium 2.0b4 (beta 4)
 %0A       

Add banner to debug output for remote webdriver initialization failure, and add comment to take out code for now fixed bug in Selenium 2.0 b4