/*
 * #%L
 * wcm.io
 * %%
 * Copyright (C) 2018 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.util;

import static io.wcm.qa.galenium.reporting.GaleniumReportUtil.MARKER_INFO;
import static io.wcm.qa.galenium.reporting.GaleniumReportUtil.getLogger;

import java.net.URI;

import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.Proxy;

import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.proxy.auth.AuthType;

/**
 * Configuring the BrowserMob Proxy.
 */
public final class BrowserMobUtil {

  private static Proxy seleniumProxy;
  private static BrowserMobProxyServer proxy;

  private BrowserMobUtil() {
    // do not instantiate
  }

  /**
   * Add basic authentication header to every request.
   * @param name user name to use for auth
   * @param pass password to use for auth
   */
  public static void addBasicAuth(String name, String pass) {
    addBasicAuth("", name, pass);
  }

  /**
   * Add basic authentication header to every request.
   * @param url to extract protected domain from
   * @param name user name to use for auth
   * @param pass password to use for auth
   */
  public static void addBasicAuth(String url, String name, String pass) {
    String domain = extractDomain(url);
    getLogger().debug(MARKER_INFO, "setting basic auth for domain '" + domain + "'");
    getBrowserMobProxy().autoAuthorization(domain, name, pass, AuthType.BASIC);
  }

  private static String extractDomain(String url) {
    String host = getHostFromUrl(url);
    String domain;
    if (StringUtils.isNotBlank(host)) {
      domain = host;
    }
    else {
      domain = url;
    }
    return domain;
  }

  private static String getHostFromUrl(String url) {
    URI rawUri = URI.create(url);
    String host = rawUri.getHost();
    return host;
  }

  /**
   * Add header to every request.
   * @param name header name
   * @param value header value
   */
  public static void addHeader(String name, String value) {
    getLogger().debug(MARKER_INFO, "adding header: " + name);
    getBrowserMobProxy().addHeader(name, value);
  }

  /**
   * @return Selenium proxy using BrowserMob Proxy
   */
  public static Proxy getSeleniumProxy() {
    if (seleniumProxy == null) {
      seleniumProxy = ClientUtil.createSeleniumProxy(getBrowserMobProxy());
    }
    return seleniumProxy;

  }

  private static BrowserMobProxy getBrowserMobProxy() {
    if (proxy == null) {
      proxy = new BrowserMobProxyServer();
      proxy.setMitmDisabled(false);
      proxy.start();
    }
    return proxy;
  }

}

@@ -906,16 +906,72 @@
 Proxy;%0A%0A
+import io.wcm.qa.galenium.exceptions.GaleniumException;%0A
 import n
@@ -1310,16 +1310,194 @@
 proxy;%0A%0A
+  static %7B%0A    if (GaleniumConfiguration.isUseBrowserMobProxy()) %7B%0A      proxy = new BrowserMobProxyServer();%0A      proxy.setMitmDisabled(false);%0A      proxy.start();%0A    %7D%0A  %7D%0A%0A
   privat
@@ -3273,122 +3273,166 @@
 if (
-proxy == null) %7B%0A      proxy = new BrowserMobProxyServer();%0A      proxy.setMitmDisabled(false);%0A     
+!GaleniumConfiguration.isUseBrowserMobProxy()) %7B%0A      throw new GaleniumException(%22set 'galenium.browsermob.proxy' to true before fetching browsermob
  proxy.
-start(
+%22
 );%0A 

initialize browsermob proxy on class initialization to avoid race conditions