/*
 * Copyright 2015 www.seleniumtests.com
 * 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.
 */

package com.seleniumtests.driver;

import org.openqa.selenium.By;
import org.openqa.selenium.UnsupportedCommandException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.events.WebDriverEventListener;

import com.seleniumtests.core.SeleniumTestsContextManager;

import com.seleniumtests.customexception.WebSessionEndedException;

public class DriverExceptionListener implements WebDriverEventListener {
    public void afterChangeValueOf(final WebElement arg0, final WebDriver arg1) { }

    public void afterClickOn(final WebElement arg0, final WebDriver arg1) { }

    public void afterFindBy(final By arg0, final WebElement arg1, final WebDriver arg2) { }

    public void afterNavigateBack(final WebDriver arg0) { }

    public void afterNavigateForward(final WebDriver arg0) { }

    @Override
    public void beforeNavigateRefresh(WebDriver webDriver) {}

    @Override
    public void afterNavigateRefresh(WebDriver webDriver) {}

    public void afterNavigateTo(final String arg0, final WebDriver arg1) { }

    public void afterScript(final String arg0, final WebDriver arg1) { }

    public void beforeChangeValueOf(final WebElement arg0, final WebDriver arg1) { }

    public void beforeClickOn(final WebElement arg0, final WebDriver arg1) { }

    public void beforeFindBy(final By arg0, final WebElement arg1, final WebDriver arg2) { }

    public void beforeNavigateBack(final WebDriver arg0) { }

    public void beforeNavigateForward(final WebDriver arg0) { }

    public void beforeNavigateTo(final String arg0, final WebDriver arg1) { }

    public void beforeScript(final String arg0, final WebDriver arg1) { }

    public void onException(final Throwable ex, final WebDriver arg1) {

        if (ex.getMessage() == null) {
            return;
        } else if (ex.getMessage().contains("Element must be user-editable in order to clear it")) {
            return;
        } else if (ex.getMessage().contains("Element is not clickable at point")) {
            return;
        } else if (ex instanceof UnsupportedCommandException) {
            return;
        } else if (ex.getMessage().contains(" read-only")) {
            return;
        } else if (ex.getMessage().contains("No response on ECMAScript evaluation command")) { // Opera

            // customexception
            for (int i = 0; i < ex.getStackTrace().length; i++) {
                String method = ex.getStackTrace()[i].getMethodName();
                if (method.contains("getTitle") || method.contains("getWindowHandle") || method.contains("click")
                        || method.contains("getPageSource")) {
                    return;
                }
            }

            ex.printStackTrace();
            // return;
        } else if (ex.getMessage().contains("Error communicating with the remote browser. It may have died.")) {

            // Session has lost connection, remove it then ignore quit() method.
            if (WebUIDriver.getWebUIDriver().getConfig().getMode() == DriverMode.ExistingGrid) {
                WebUIDriver.setWebDriver(null);
                throw new WebSessionEndedException(ex);
            }

            return;
        } else if (ex instanceof org.openqa.selenium.remote.UnreachableBrowserException) {
            return;
        } else if (ex instanceof org.openqa.selenium.UnsupportedCommandException) {
            return;
        } else {
            String message = ex.getMessage().split("\\n")[0];
            System.out.println("Got customexception:" + message);
            if (message.matches("Session (/S*) was terminated due to(.|\\n)*")
                    || message.matches("cannot forward the request Connection to(.|\\n)*")) {
                WebUIDriver.setWebDriver(null); // can't quit anymore, save time.

                // since the session was
                // terminated.
                throw new WebSessionEndedException(ex);
            }
        }

        for (int i = 0; i < ex.getStackTrace().length; i++) // avoid dead loop
        {
            String method = ex.getStackTrace()[i].getMethodName();
            if (method.contains("getScreenshotAs") || method.contains("captureWebPageSnapshot")) {
                return;
            }
        }

        if (arg1 != null) {

            try {
                System.out.println("Got customexception" + ex.getMessage());
                if (SeleniumTestsContextManager.getThreadContext().getTestType().equalsIgnoreCase(
                            TestType.WEB.toString())) {
                    new ScreenshotUtil(arg1).capturePageSnapshotOnException();
                } else {
                    System.out.println("Capture screenshot is not available for appium");
                }
            } catch (Exception e) {

                // Ignore all exceptions
                e.printStackTrace();
            }
        }
    }
}

@@ -617,24 +617,150 @@
 ts.driver;%0A%0A
+import com.seleniumtests.core.SeleniumTestsContextManager;%0Aimport com.seleniumtests.customexception.WebSessionEndedException;%0A
 import org.o
@@ -982,136 +982,8 @@
 r;%0A%0A
-import com.seleniumtests.core.SeleniumTestsContextManager;%0A%0Aimport com.seleniumtests.customexception.WebSessionEndedException;%0A%0A
 publ
@@ -1073,16 +1073,110 @@
 d afterC
+lickOn(final WebElement arg0, final WebDriver arg1) %7B %7D%0A%0A    @Override%0A    public void beforeC
 hangeVal
@@ -1189,36 +1189,42 @@
 inal WebElement 
-arg0
+webElement
 , final WebDrive
@@ -1221,34 +1221,102 @@
 l WebDriver 
-arg1) %7B %7D%0A
+webDriver, final CharSequence%5B%5D charSequences) %7B%0A        %0A    %7D%0A%0A    @Override
 %0A    public 
@@ -1318,38 +1318,44 @@
 blic void afterC
-lickOn
+hangeValueOf
 (final WebElemen
@@ -1348,36 +1348,42 @@
 inal WebElement 
-arg0
+webElement
 , final WebDrive
@@ -1376,39 +1376,85 @@
 final WebDriver 
-arg1) %7B
+webDriver, final CharSequence%5B%5D charSequences) %7B%0A%0A   
  %7D%0A%0A    public v
@@ -1703,32 +1703,38 @@
 NavigateRefresh(
+final 
 WebDriver webDri
@@ -1793,16 +1793,22 @@
 Refresh(
+final 
 WebDrive
@@ -1980,94 +1980,8 @@
  %7D%0A%0A
-    public void beforeChangeValueOf(final WebElement arg0, final WebDriver arg1) %7B %7D%0A%0A
     
@@ -3163,32 +3163,38 @@
                 
+final 
 String method = 
@@ -4194,32 +4194,38 @@
 e %7B%0A            
+final 
 String message =
@@ -4834,16 +4834,22 @@
         
+final 
 String m
@@ -5555,16 +5555,22 @@
  catch (
+final 
 Exceptio

implement unused methods