/*
 * (C) Copyright 2015 Boni Garcia (http://bonigarcia.github.io/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */
package io.github.bonigarcia.wdm;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.opera.OperaDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;

/**
 * Generic manager.
 *
 * @author Boni Garcia (boni.gg@gmail.com)
 * @since 1.3.1
 */
public class WebDriverManager extends BrowserManager {

	private static BrowserManager instance;

	private static Class<? extends BrowserManager> browserManagerClass;

	protected WebDriverManager() {
	}

	public static synchronized BrowserManager getInstance(
			Class<? extends WebDriver> webDriverClass) {
		if (instance == null) {
			if (webDriverClass.equals(ChromeDriver.class)) {
				browserManagerClass = ChromeDriverManager.class;

			} else if (webDriverClass.equals(OperaDriver.class)) {
				browserManagerClass = OperaDriverManager.class;

			} else if (webDriverClass.equals(InternetExplorerDriver.class)) {
				browserManagerClass = InternetExplorerDriverManager.class;

			} else if (webDriverClass.equals(EdgeDriver.class)) {
				browserManagerClass = EdgeDriverManager.class;

			} else if (webDriverClass.equals(PhantomJSDriver.class)) {
				browserManagerClass = PhantomJsDriverManager.class;

			} else if (webDriverClass.equals(MarionetteDriverManager.class)) {
				browserManagerClass = MarionetteDriverManager.class;

			} else {
				browserManagerClass = VoidDriverManager.class;
			}

			try {
				instance = browserManagerClass.newInstance();
			} catch (Throwable e) {
				String errMessage = "Error creating WebDriverManager";
				log.error(errMessage, e);
				throw new RuntimeException(errMessage, e);
			}
		}
		return instance;
	}

	@Override
	public List<URL> getDrivers() throws Exception {
		return instance.getDrivers();
	}

	@Override
	protected String getExportParameter() {
		return instance.getExportParameter();
	}

	@Override
	protected String getDriverVersion() {
		return instance.getDriverVersion();
	}

	@Override
	protected URL getDriverUrl() throws MalformedURLException {
		return instance.getDriverUrl();
	}

	@Override
	protected List<String> getDriverName() {
		return instance.getDriverName();
	}

}

@@ -838,32 +838,85 @@
 dge.EdgeDriver;%0A
+import org.openqa.selenium.firefox.MarionetteDriver;%0A
 import org.openq
@@ -1456,35 +1456,8 @@
 ) %7B%0A
-%09%09if (instance == null) %7B%0A%09
 %09%09if
@@ -1498,33 +1498,32 @@
 er.class)) %7B%0A%09%09%09
-%09
 browserManagerCl
@@ -1548,33 +1548,32 @@
 Manager.class;%0A%0A
-%09
 %09%09%7D else if (web
@@ -1605,33 +1605,32 @@
 river.class)) %7B%0A
-%09
 %09%09%09browserManage
@@ -1659,33 +1659,32 @@
 nager.class;%0A%0A%09%09
-%09
 %7D else if (webDr
@@ -1725,33 +1725,32 @@
 river.class)) %7B%0A
-%09
 %09%09%09browserManage
@@ -1790,33 +1790,32 @@
 nager.class;%0A%0A%09%09
-%09
 %7D else if (webDr
@@ -1844,33 +1844,32 @@
 river.class)) %7B%0A
-%09
 %09%09%09browserManage
@@ -1897,33 +1897,32 @@
 nager.class;%0A%0A%09%09
-%09
 %7D else if (webDr
@@ -1956,33 +1956,32 @@
 river.class)) %7B%0A
-%09
 %09%09%09browserManage
@@ -2018,25 +2018,24 @@
 r.class;%0A%0A%09%09
-%09
 %7D else if (w
@@ -2067,31 +2067,24 @@
 onetteDriver
-Manager
 .class)) %7B%0A%09
@@ -2082,17 +2082,16 @@
 ass)) %7B%0A
-%09
 %09%09%09brows
@@ -2141,17 +2141,16 @@
 ass;%0A%0A%09%09
-%09
 %7D else %7B
@@ -2150,17 +2150,16 @@
  else %7B%0A
-%09
 %09%09%09brows
@@ -2202,21 +2202,19 @@
 lass;%0A%09%09
-%09
 %7D%0A%0A
-%09
 %09%09try %7B%0A
@@ -2214,16 +2214,77 @@
 %09try %7B%0A%09
+%09%09log.debug(%22Creating instance of %7B%7D%22, browserManagerClass);%0A
 %09%09%09insta
@@ -2326,17 +2326,16 @@
 ce();%0A%09%09
-%09
 %7D catch 
@@ -2350,17 +2350,16 @@
 le e) %7B%0A
-%09
 %09%09%09Strin
@@ -2411,17 +2411,16 @@
 er%22;%0A%09%09%09
-%09
 log.erro
@@ -2437,17 +2437,16 @@
 ge, e);%0A
-%09
 %09%09%09throw
@@ -2487,13 +2487,8 @@
 e);%0A
-%09%09%09%7D%0A
 %09%09%7D%0A

correct support for Marionette in generic manager