import pytest
import os
from selenium import webdriver
from tlib.base import AndroidHelper
from tlib.base.TestHelper import webdriver_chrome_executable, webdriver_ie_executable
from _pytest.python import FixtureRequest
import time

def pytest_addoption(parser):
    """
    Options supported by pytest's selenium plug-in
    """
    group = parser.getgroup("selenium", "Testing with the selenium framework")

    group.addoption(
        "--mobile_base_url",
        action="store",
        dest="mobile_base_url",
        help="mobile base url of the mobile web server used for testing")

    group.addoption(
        "--browser",
        action="store",
        dest="browser",
        choices=["chrome", "firefox", "firefox_no_js","ie", "android"],
        help="Browser used for running test cases")

    group.addoption(
        "--chromedriver_version",
        action="store",
        dest="chromedriver_version",
        default="latest",
        help="Version of chromedriver to use")

    group.addoption(
        "--serial_id",
        action="store",
        dest="serial_id",
        help="Serial of the android device or simulator where Android tests will be run")

#noinspection PyShadowingNames,PyUnresolvedReferences
@pytest.fixture(scope='class')
def selendroid_server(request, tlib_logger, adb_logger):
    """
    Creates a server for native apps
    """
    apk_path = request.config.getoption("apk_path")
    if os.path.exists(apk_path):
        tlib_logger.debug("Creating webdriver for Android")
    #Start selendroid server
    process = AndroidHelper.start_selendroid_server(tlib_logger, adb_logger, apk_path)

    if process:
        request.addfinalizer(process.kill)


#noinspection PyShadowingNames,PyUnresolvedReferences
@pytest.fixture(scope='function')
def driver(request, tlib_logger, selendroid_server):
    """
    Fixture to creates a Webdriver object to interact with native apps specified by command line parameters
    @param request: Object that gives access to the requesting test context
    @type request: FixtureRequest
    @param tlib_logger: logger for tlib related actions
    @type tlib_logger: logging.logger
    """
    serial_id = request.config.getoption("serial_id")
    appId = AndroidHelper.get_android_app_id()
    capabilities = {'aut': appId}
    if serial_id is None:
        tlib_logger.warn("Parameter --serial_id was not given. Running test on default device")
    else:
        capabilities['serial'] = serial_id
    dr = webdriver.Remote(desired_capabilities=capabilities)

    request.addfinalizer(dr.quit)
    return dr


#noinspection PyShadowingNames,PyUnresolvedReferences
@pytest.fixture(scope='class')
def browser(request, tlib_logger, adb_logger, chromedriver_version):
    """
    Fixture to create a browser as specified by the command line parameter --browser\n
    """
    browser = request.config.getoption("browser")
    return get_browser(request, tlib_logger, adb_logger, browser, chromedriver_version)


@pytest.fixture(scope='class')
def chromedriver_version(request, tlib_logger):
    """
    Fixture to create a browser as specified by the command line parameter --browser\n
    """
    version = request.config.getoption("chromedriver_version")
    tlib_logger.info("Using chromedriver version = '%s'" % version)
    return version


def get_browser(request, tlib_logger, adb_logger, browser_str, chromedriver="latest"):
    """
    Creates a Webdriver object to interact with browser specified in browser_str parameter
    @param request: Object that gives access to the requesting test context
    @type request: FixtureRequest
    @param tlib_logger: logger for tlib related actions
    @type tlib_logger: logging.logger
    @param adb_logger: logger for adb related actions
    @type adb_logger: logging.logger
    @param browser_str: browser to launch. It cna be firefox, chrome, ie or android
    @type browser_str: str
    @param chromedriver: Version of ChromeDriver to use. Pass 'latest' to use the latest version
    @type chromedriver: str
    """
    b = None

    #Don't create a browser object is --browser was not specified
    if browser_str is None:
        tlib_logger.warn("Parameter browser was not specified")
        pytest.fail("Parameter browser was not specified")
    else:
        if browser_str == "ie":
            tlib_logger.debug("Creating webdriver for IE")
            b = webdriver.Ie(webdriver_ie_executable())
            b.maximize_window()
            request.addfinalizer(b.quit)
        elif browser_str == "chrome":
            tlib_logger.debug("Creating webdriver for Chrome")
            b = webdriver.Chrome(webdriver_chrome_executable(chromedriver))
            b.maximize_window()
            request.addfinalizer(b.quit)
        elif browser_str == "firefox":
            tlib_logger.debug("Creating webdriver for Firefox")
            b = webdriver.Firefox()
            b.maximize_window()
            request.addfinalizer(b.quit)
        elif browser_str == "firefox_no_js":
            tlib_logger.debug("Creating webdriver for Firefox with JavaScript disabled")
            profile = webdriver.FirefoxProfile()
            profile.set_preference("javascript.enabled", False)
            b = webdriver.Firefox(profile)
            b.maximize_window()
            request.addfinalizer(b.quit)
        elif browser_str == "android":
            tlib_logger.debug("Creating webdriver for Android")

            serial_id = request.config.getoption("serial_id")
            if serial_id is None:
                tlib_logger.warn("Parameter --serial_id was not given. Running test on default device")

            #Start android server
            AndroidHelper.setup_webdriver(tlib_logger, adb_logger, serial_id)
            b = webdriver.Remote(command_executor='http://localhost:8080/wd/hub',
                                 desired_capabilities=webdriver.DesiredCapabilities.ANDROID)

        else:
            #noinspection PyUnresolvedReferences
            tlib_logger.warn("{browser}s is not a valid browser".format(browser=browser_str))
            pytest.fail("{browser}s is not a valid browser".format(browser=browser_str))

        def fin():
            # noinspection PyStatementEffect
            if browser_str == "android":
                b.quit
                AndroidHelper.teardown_webdriver(tlib_logger, adb_logger, serial_id)

        request.addfinalizer(fin)

    return b


#noinspection PyUnresolvedReferences
@pytest.fixture(scope="class")
def mobile_base_url(request, tlib_logger):
    """
    Returns value of --mobile_base_url command line parameter
    """
    if request.config.getoption("mobile_base_url") is None:
        #noinspection PyUnresolvedReferences
        tlib_logger.warn("parameter --mobile_base_url was not specified")
        pytest.fail("parameter --mobile_base_url was not specified")
        return None
    else:
        return request.config.getoption("mobile_base_url")
