/*
   * Factory method to return a WebDriver instance given the browser to hit
   *
   * @param browser : String representing the local browser to hit
   *
   * @param username : username for BASIC authentication on the page to test
   *
   * @param password : password for BASIC authentication on the page to test
   *
   * @return WebDriver instance
   */
  public static WebDriver getInstance(String browser, String username, String password) {

    if (webDriver != null) {
      return webDriver;
    }

    if (CHROME.equals(browser)) {
      webDriver = new ChromeDriver();

    } else if (FIREFOX.equals(browser)) {

      FirefoxProfile ffProfile = new FirefoxProfile();

      // Authenication Hack for Firefox
      if (username != null && password != null) {
        ffProfile.setPreference("network.http.phishy-userpass-length", 255);
      }

      webDriver = new FirefoxDriver(ffProfile);

    } else if (INTERNET_EXPLORER.equals(browser)) {
      webDriver = new InternetExplorerDriver();

    } else {

      // HTMLunit Check
      if (username != null && password != null) {
        webDriver = (HtmlUnitDriver) AuthenticatedHtmlUnitDriver.create(username, password);
      } else {
        webDriver = new HtmlUnitDriver(true);
      }
    }

    return webDriver;
  }
  /*
   * Factory method to return a RemoteWebDriver instance given the url of the
   * Grid hub and a Browser instance.
   *
   * @param gridHubUrl : grid hub URI
   *
   * @param browser : Browser object containing info around the browser to hit
   *
   * @param username : username for BASIC authentication on the page to test
   *
   * @param password : password for BASIC authentication on the page to test
   *
   * @return RemoteWebDriver
   */
  public static WebDriver getInstance(
      String gridHubUrl, Browser browser, String username, String password) {

    WebDriver webDriver = null;

    DesiredCapabilities capability = new DesiredCapabilities();
    String browserName = browser.getName();
    capability.setJavascriptEnabled(true);

    // In case there is no Hub
    if (gridHubUrl == null || gridHubUrl.length() == 0) {
      return getInstance(browserName, username, password);
    }

    if (CHROME.equals(browserName)) {
      capability = DesiredCapabilities.chrome();
    } else if (FIREFOX.equals(browserName)) {
      capability = DesiredCapabilities.firefox();

      FirefoxProfile ffProfile = new FirefoxProfile();

      // Authenication Hack for Firefox
      if (username != null && password != null) {
        ffProfile.setPreference("network.http.phishy-userpass-length", 255);
        capability.setCapability(FirefoxDriver.PROFILE, ffProfile);
      }

      capability.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
    } else if (INTERNET_EXPLORER.equals(browserName)) {

      capability = DesiredCapabilities.internetExplorer();
      capability.setCapability(
          InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
    } else if (SAFARI.equals(browserName)) {
      capability = DesiredCapabilities.safari();
    } else if (ANDROID.equals(browserName)) {
      capability = DesiredCapabilities.android();
    } else if (IPHONE.equals(browserName)) {
      capability = DesiredCapabilities.iphone();
    } else {

      capability = DesiredCapabilities.htmlUnit();
      // HTMLunit Check
      if (username != null && password != null) {
        webDriver = (HtmlUnitDriver) AuthenticatedHtmlUnitDriver.create(username, password);
      } else {
        webDriver = new HtmlUnitDriver(true);
      }

      return webDriver;
    }

    capability = setVersionAndPlatform(capability, browser.getVersion(), browser.getPlatform());

    // Create Remote WebDriver
    try {
      webDriver = new RemoteWebDriver(new URL(gridHubUrl), capability);
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }

    return webDriver;
  }