import os
import json
import requests
from typing import Any, Iterable

from awe.util.logging import logger

DEFAULT_HTTP_TIMEOUT = float(os.getenv("HTTP_TIMEOUT_SECONDS", "120"))


def _request(method: str, url: str, expected_statuses: Iterable[int] = (200,), **kwargs):
    timeout = kwargs.pop("timeout", DEFAULT_HTTP_TIMEOUT)
    try:
        response = requests.request(method, url, timeout=timeout, **kwargs)
    except requests.RequestException as error:
        logger.error(f"HTTP {method.upper()} {url} failed: {error}")
        raise

    if response.status_code not in expected_statuses:
        logger.warning(
            f"HTTP {method.upper()} {url} returned status {response.status_code}: {response.text[:500]}"
        )
    return response


def post_request(server_address, endpoint, data=None, timeout=None):
    url = f"http://{server_address}{endpoint}"
    headers = {"Content-Type": "application/json"} if data else {}
    json_data = json.dumps(data).encode("utf-8") if data else None
    return _request("post", url, headers=headers, data=json_data, timeout=timeout)


def get_request(url: str, params=None, timeout=None, expected_statuses: Iterable[int] = (200,)):
    return _request("get", url, params=params, timeout=timeout, expected_statuses=expected_statuses)


def get_json(url: str, params=None, timeout=None):
    response = get_request(url, params=params, timeout=timeout)
    return response.json()


def get_content(url: str, params=None, timeout=None):
    response = get_request(url, params=params, timeout=timeout)
    return response.content


def post_multipart(url: str, files: dict[str, Any], timeout=None):
    return _request("post", url, files=files, timeout=timeout)