import json
from typing import Union, Dict

from requests import Request, Session, RequestException

from .configuration import Configuration
from .errors import NetworkError
from .utils import JSONEncoder
from . import version


class Requestor(object):
    def __init__(self, configuration: Configuration):
        self._user_agent = f"domainmaster-python/{version.__version__}"
        self._configuration = configuration
        self._session = Session()
        self._session.auth = (configuration.username, 'password')

    def request(
        self, payload: dict = None, query: dict = None
    ) -> Union[str, Dict]:
        req = Request(
            url=self._configuration.environment.api_url,
            headers={
                "User-Agent": self._user_agent,
            },
        )

        if payload and isinstance(payload, dict):
            req.data = json.dumps(payload, cls=JSONEncoder)
            req.headers['Content-Type'] = 'application/json'

        if query and isinstance(query, dict):
            req.params = query

        prepared = req.prepare()

        try:
            r = self._session.send(
                prepared,
                timeout=self._configuration.timeout
            )
            r.raise_for_status()
        except RequestException as e:
            raise NetworkError(prepared, previous=e)

        data = r.text

        return data

    def __str__(self) -> str:
        return self._user_agent
