/*
 * #%L
 * wcm.io
 * %%
 * Copyright (C) 2017 wcm.io
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package io.wcm.qa.galenium.webdriver;

import static io.wcm.qa.galenium.configuration.GaleniumConfiguration.isWebDriverAcceptTrustedSslCertificatesOnly;
import static io.wcm.qa.galenium.configuration.GaleniumConfiguration.isWebDriverRefuseSslCertificates;

import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.remote.CapabilityType;
import org.slf4j.Logger;

import io.wcm.qa.galenium.configuration.GaleniumConfiguration;
import io.wcm.qa.galenium.reporting.GaleniumReportUtil;
import io.wcm.qa.galenium.util.BrowserMobUtil;
import io.wcm.qa.galenium.util.GaleniumContext;

abstract class OptionsProvider<O extends MutableCapabilities> {

  /**
   * @return capabilities for browser
   */
  public O getOptions() {
    O options = getBrowserSpecificOptions();
    options = mergeCommonOptions(options);
    GaleniumReportUtil.getLogger().info("Done generating capabilities");
    log(options);
    return options;
  }

  /**
   * Capabilities specific to this browser type. These are automatically included in {@link #getOptions()}.
   * Override when implementing new browser types.
   * @return capabilities for browser
   */
  protected abstract O getBrowserSpecificOptions();

  protected O getCommonOptions() {
    O options = newOptions();
    options.setCapability(CapabilityType.ACCEPT_SSL_CERTS, !isWebDriverRefuseSslCertificates());
    options.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS, !isWebDriverAcceptTrustedSslCertificatesOnly());

    if (GaleniumConfiguration.isUseBrowserMobProxy()) {
      options.setCapability(CapabilityType.PROXY, BrowserMobUtil.getSeleniumProxy());
    }

    if (StringUtils.isNotEmpty(GaleniumConfiguration.getHttpsProxyHost()) && StringUtils.isNotEmpty(GaleniumConfiguration.getHttpsProxyPort()) && !GaleniumConfiguration.isUseBrowserMobProxy()){
      Proxy proxy = new Proxy();
      proxy.setSslProxy(GaleniumConfiguration.getHttpsProxyHost() + ":" + GaleniumConfiguration.getHttpsProxyPort());
      getLogger().debug("Using Proxy Configuration for webdriver with host: " + GaleniumConfiguration.getHttpsProxyHost()+ " and Port: "  + GaleniumConfiguration.getHttpsProxyPort());
      options.setCapability(CapabilityType.PROXY, proxy);
    }
    return options;
  }

  protected Logger getLogger() {
    return WebDriverManager.getLogger();
  }

  protected abstract void log(O options);

  @SuppressWarnings("unchecked")
  protected O mergeCommonOptions(O options) {
    return (O)options.merge(getCommonOptions());
  }

  protected abstract O newOptions();
}

@@ -1250,56 +1250,8 @@
 til;
-%0Aimport io.wcm.qa.galenium.util.GaleniumContext;
 %0A%0Aab
@@ -2139,56 +2139,70 @@
     
-if (GaleniumConfiguration.isUseBrowserMobProxy()
+Proxy proxyToUse = getProxyToUse();%0A    if (proxyToUse != null
 ) %7B%0A
@@ -2255,41 +2255,18 @@
 XY, 
-BrowserMobUtil.getSeleniumProxy()
+proxyToUse
 );%0A 
@@ -2274,214 +2274,255 @@
   %7D%0A
-%0A
     
-if (StringUtils.isNotEmpty(GaleniumConfiguration.getHttpsProxyHost()) && StringUtils.isNotEmpty(GaleniumConfiguration.getHttpsProxyPort()) && !GaleniumConfiguration.isUseBrowserMob
+return options;%0A  %7D%0A%0A  private static Proxy getProxyToUse() %7B%0A    Proxy proxy = null;%0A    if (GaleniumConfiguration.isUseBrowserMobProxy()) %7B%0A      proxy = BrowserMobUtil.getSelenium
 Proxy()
-)%7B
+;
 %0A    
-  Proxy
+%7D%0A    else if (isHttpsProxyConfigured()) %7B%0A     
  pro
@@ -2549,26 +2549,27 @@
     
-proxy.setSslProxy(
+String proxyHost = 
 Gale
@@ -2609,16 +2609,34 @@
 st()
- + %22:%22 +
+;%0A      String proxyPort =
  Gal
@@ -2677,151 +2677,316 @@
 rt()
-);%0A      getLogger().debug(%22Using Proxy Configuration for webdriver with host: %22 + GaleniumConfiguration.getHttpsProxyHost()+ %22 and Port: %22  + 
+;%0A      proxy.setSslProxy(proxyHost + %22:%22 + proxyPort);%0A      WebDriverManager.getLogger().debug(%22Using Proxy Configuration for webdriver with host: %22 + proxyHost + %22 and Port: %22 + proxyPort);%0A    %7D%0A    return proxy;%0A  %7D%0A%0A  private static boolean isHttpsProxyConfigured() %7B%0A    return StringUtils.isNotEmpty(
 Gale
@@ -3020,99 +3020,84 @@
 roxy
-Por
+Hos
 t())
-;%0A      options.setCapability(CapabilityType.PROXY, proxy);%0A    %7D%0A    return options
+ && StringUtils.isNotEmpty(GaleniumConfiguration.getHttpsProxyPort())
 ;%0A  

refactor for readability