# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you 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.

import warnings
from abc import ABCMeta, abstractmethod
from enum import Enum
from typing import Optional

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.common.proxy import Proxy


class PageLoadStrategy(str, Enum):
    """Enum of possible page load strategies.

    Selenium support following strategies:
        * normal (default) - waits for all resources to download
        * eager - DOM access is ready, but other resources like images may still be loading
        * none - does not block `WebDriver` at all

    Docs: https://www.selenium.dev/documentation/webdriver/drivers/options/#pageloadstrategy.
    """

    normal = "normal"
    eager = "eager"
    none = "none"


class _BaseOptionsDescriptor:
    def __init__(self, name):
        self.name = name

    def __get__(self, obj, cls):
        if self.name == "enableBidi":
            # whether BiDi is or will be enabled
            value = obj._caps.get("webSocketUrl")
            return value is True or isinstance(value, str)
        if self.name == "webSocketUrl":
            # Return socket url or None if not created yet
            value = obj._caps.get(self.name)
            return None if not isinstance(value, str) else value
        if self.name in ("acceptInsecureCerts", "strictFileInteractability", "setWindowRect", "se:downloadsEnabled"):
            return obj._caps.get(self.name, False)
        return obj._caps.get(self.name)

    def __set__(self, obj, value):
        if self.name == "enableBidi":
            obj.set_capability("webSocketUrl", value)
        else:
            obj.set_capability(self.name, value)


class _PageLoadStrategyDescriptor:
    """Determines the point at which a navigation command is returned.

    See:
      - https://w3c.github.io/webdriver/#dfn-table-of-page-load-strategies.

    Args:
        strategy: the strategy corresponding to a document readiness state
    """

    def __init__(self, name):
        self.name = name

    def __get__(self, obj, cls):
        return obj._caps.get(self.name)

    def __set__(self, obj, value):
        if value in ("normal", "eager", "none"):
            obj.set_capability(self.name, value)
        else:
            raise ValueError("Strategy can only be one of the following: normal, eager, none")


class _UnHandledPromptBehaviorDescriptor:
    """How the driver should respond when an alert is present and the command sent is not handling the alert.

    See:
      - https://w3c.github.io/webdriver/#dfn-table-of-page-load-strategies:

    Args:
        behavior: behavior to use when an alert is encountered

    Returns:
        Values for implicit timeout, pageLoad timeout and script timeout if set (in milliseconds)
    """

    def __init__(self, name):
        self.name = name

    def __get__(self, obj, cls):
        return obj._caps.get(self.name)

    def __set__(self, obj, value):
        if value in ("dismiss", "accept", "dismiss and notify", "accept and notify", "ignore"):
            obj.set_capability(self.name, value)
        else:
            raise ValueError(
                "Behavior can only be one of the following: dismiss, accept, dismiss and notify, "
                "accept and notify, ignore"
            )


class _TimeoutsDescriptor:
    """How long the driver should wait for actions to complete before returning an error.

    See:
      - https://w3c.github.io/webdriver/#timeouts

    Args:
        timeouts: values in milliseconds for implicit wait, page load and script timeout

    Returns:
        Values for implicit timeout, pageLoad timeout and script timeout if set (in milliseconds)
    """

    def __init__(self, name):
        self.name = name

    def __get__(self, obj, cls):
        return obj._caps.get(self.name)

    def __set__(self, obj, value):
        if all(x in ("implicit", "pageLoad", "script") for x in value.keys()):
            obj.set_capability(self.name, value)
        else:
            raise ValueError("Timeout keys can only be one of the following: implicit, pageLoad, script")


class _ProxyDescriptor:
    """Descriptor for proxy property access.

    Returns:
        Proxy if set, otherwise None.
    """

    def __init__(self, name):
        self.name = name

    def __get__(self, obj, cls):
        return obj._proxy

    def __set__(self, obj, value):
        if not isinstance(value, Proxy):
            raise InvalidArgumentException("Only Proxy objects can be passed in.")
        obj._proxy = value
        obj._caps[self.name] = value.to_capabilities()


class BaseOptions(metaclass=ABCMeta):
    """Base class for individual browser options."""

    browser_version = _BaseOptionsDescriptor("browserVersion")
    """Gets and Sets the version of the browser.

    Usage:
        - Get: `self.browser_version`
        - Set: `self.browser_version = value`

    Args:
        value: str

    Returns:
        str when getting, None when setting.
    """

    platform_name = _BaseOptionsDescriptor("platformName")
    """Gets and Sets name of the platform.

    Usage:
        - Get: `self.platform_name`
        - Set: `self.platform_name = value`

    Args:
        value: str

    Returns:
        str when getting, None when setting.
    """

    accept_insecure_certs = _BaseOptionsDescriptor("acceptInsecureCerts")
    """Gets and Set whether the session accepts insecure certificates.

    Usage:
        - Get: `self.accept_insecure_certs`
        - Set: `self.accept_insecure_certs = value`

    Args:
        value: bool

    Returns:
        bool when getting, None when setting.
    """

    strict_file_interactability = _BaseOptionsDescriptor("strictFileInteractability")
    """Gets and Sets whether session is about file interactability.

    Usage:
        - Get: `self.strict_file_interactability`
        - Set: `self.strict_file_interactability = value`

    Args:
        value: bool

    Returns:
        bool when getting, None when setting.
    """

    set_window_rect = _BaseOptionsDescriptor("setWindowRect")
    """Gets and Sets window size and position.

    Usage:
        - Get: `self.set_window_rect`
        - Set: `self.set_window_rect = value`

    Args:
        value: bool

    Returns:
        bool when getting, None when setting.
    """

    enable_bidi = _BaseOptionsDescriptor("enableBidi")
    """Gets and Set whether the session has WebDriverBiDi enabled.

    Usage:
        - Get: `self.enable_bidi`
        - Set: `self.enable_bidi = value`

    Args:
        value: bool

    Returns:
        bool when getting, None when setting.
    """

    page_load_strategy = _PageLoadStrategyDescriptor("pageLoadStrategy")
    """Gets and Sets page load strategy, the default is "normal".

    Usage:
        - Get: `self.page_load_strategy`
        - Set: `self.page_load_strategy = value`

    Args:
        value: str

    Returns:
        str when getting, None when setting.
    """

    unhandled_prompt_behavior = _UnHandledPromptBehaviorDescriptor("unhandledPromptBehavior")
    """Gets and Sets unhandled prompt behavior, the default is "dismiss and notify".

    Usage:
        - Get: `self.unhandled_prompt_behavior`
        - Set: `self.unhandled_prompt_behavior = value`

    Args:
        value: str

    Returns:
        str when getting, None when setting.
    """

    timeouts = _TimeoutsDescriptor("timeouts")
    """Gets and Sets implicit timeout, pageLoad timeout and script timeout if set (in milliseconds).

    Usage:
        - Get: `self.timeouts`
        - Set: `self.timeouts = value`

    Args:
        value: dict

    Returns:
        dict when getting, None when setting.
    """

    proxy = _ProxyDescriptor("proxy")
    """Sets and Gets Proxy.

    Usage:
        - Get: `self.proxy`
        - Set: `self.proxy = value`

    Args:
        value: Proxy

    Returns:
        Proxy when getting, None when setting.
    """

    enable_downloads = _BaseOptionsDescriptor("se:downloadsEnabled")
    """Gets and Sets whether session can download files.

    Usage:
        - Get: `self.enable_downloads`
        - Set: `self.enable_downloads = value`

    Args:
        value: bool

    Returns:
        bool when getting, None when setting.
    """

    web_socket_url = _BaseOptionsDescriptor("webSocketUrl")
    """Gets and Sets WebSocket URL.

    Usage:
        - Get: `self.web_socket_url`
        - Set: `self.web_socket_url = value`

    Args:
        value: str

    Returns:
        str when getting, None when setting.
    """

    def __init__(self) -> None:
        super().__init__()
        self._caps = self.default_capabilities
        self._proxy = None
        self.set_capability("pageLoadStrategy", PageLoadStrategy.normal)
        self.mobile_options: Optional[dict[str, str]] = None
        self._ignore_local_proxy = False

    @property
    def capabilities(self):
        return self._caps

    def set_capability(self, name, value) -> None:
        """Sets a capability."""
        self._caps[name] = value

    def enable_mobile(
        self,
        android_package: Optional[str] = None,
        android_activity: Optional[str] = None,
        device_serial: Optional[str] = None,
    ) -> None:
        """Enables mobile browser use for browsers that support it.

        Args:
            android_package: The name of the android package to start
            android_activity: The name of the android activity
            device_serial: The device serial number
        """
        if not android_package:
            raise AttributeError("android_package must be passed in")
        self.mobile_options = {"androidPackage": android_package}
        if android_activity:
            self.mobile_options["androidActivity"] = android_activity
        if device_serial:
            self.mobile_options["androidDeviceSerial"] = device_serial

    @abstractmethod
    def to_capabilities(self):
        """Convert options into capabilities dictionary."""

    @property
    @abstractmethod
    def default_capabilities(self):
        """Return minimal capabilities necessary as a dictionary."""

    def ignore_local_proxy_environment_variables(self) -> None:
        """Ignore HTTP_PROXY and HTTPS_PROXY environment variables."""
        self._ignore_local_proxy = True


class ArgOptions(BaseOptions):
    BINARY_LOCATION_ERROR = "Binary Location Must be a String"
    # FedCM capability key
    FEDCM_CAPABILITY = "fedcm:accounts"

    def __init__(self) -> None:
        super().__init__()
        self._arguments: list[str] = []

    @property
    def arguments(self):
        """Returns a list of arguments needed for the browser."""
        return self._arguments

    def add_argument(self, argument: str) -> None:
        """Adds an argument to the list.

        Args:
            argument: Sets the arguments
        """
        if argument:
            self._arguments.append(argument)
        else:
            raise ValueError("argument can not be null")

    def ignore_local_proxy_environment_variables(self) -> None:
        """Ignore HTTP_PROXY and HTTPS_PROXY environment variables.

        This method is deprecated; use a Proxy instance with ProxyType.DIRECT instead.
        """
        warnings.warn(
            "using ignore_local_proxy_environment_variables in Options has been deprecated, "
            "instead, create a Proxy instance with ProxyType.DIRECT to ignore proxy settings, "
            "pass the proxy instance into a ClientConfig constructor, "
            "pass the client config instance into the Webdriver constructor",
            DeprecationWarning,
            stacklevel=2,
        )

        super().ignore_local_proxy_environment_variables()

    def to_capabilities(self):
        return self._caps

    @property
    def default_capabilities(self):
        return {}
