# -*- coding: utf-8 -*-
"""Тест логов и JSON-записи: библиотека httpx (sync + async)."""
import asyncio
import httpx

from src.request_pydantic_decorator import (
    validate_response,
    request_logging,
    ResponseValidator,
    Exceptions,
    status_code_is,
)

OUTPUT_DIR = "output/test_httpx"

validator_ok = ResponseValidator().status_code().whitelist([200])

validator_auth = (
    ResponseValidator()
    .when_all(status_code_is(401), raise_as=Exceptions.Auth.TokenExpired)
    .status_code().whitelist([200])
)


class ApiClient:

    @request_logging(save_errors_to_file=True, errors_output_dir=OUTPUT_DIR)
    @validate_response(validator=validator_ok)
    def get_ok_sync(self):
        with httpx.Client(verify=False) as client:
            return client.get("https://httpbin.org/status/200")

    @request_logging(save_errors_to_file=True, errors_output_dir=OUTPUT_DIR)
    @validate_response(validator=validator_ok)
    def get_500_sync(self):
        with httpx.Client(verify=False) as client:
            return client.get("https://httpbin.org/status/500")

    @request_logging(save_errors_to_file=True, errors_output_dir=OUTPUT_DIR)
    @validate_response(validator=validator_auth)
    async def get_401_async(self):
        async with httpx.AsyncClient(verify=False) as client:
            return await client.get("https://httpbin.org/status/401")

    @request_logging(save_errors_to_file=True, errors_output_dir=OUTPUT_DIR)
    @validate_response(validator=validator_ok)
    async def post_json_async(self):
        async with httpx.AsyncClient(verify=False) as client:
            return await client.post(
                "https://httpbin.org/status/500",
                json={"user": "admin", "token": "xyz"},
            )


async def main():
    client = ApiClient()
    print("=== httpx ===\n")

    # 1. Sync OK
    try:
        r = client.get_ok_sync()
        print(f"[OK]  {r.response.status_code} {r.response.url}")
    except Exception as e:
        print(f"[ERR] {type(e).__name__}: {e}")

    # 2. Sync 500
    try:
        r = client.get_500_sync()
    except Exceptions.Validation.StatusCode as e:
        print(f"[ERR] {type(e).__name__}: {e}")

    # 3. Async 401 → TokenExpired
    try:
        r = await client.get_401_async()
    except Exceptions.Auth.TokenExpired as e:
        print(f"[ERR] {type(e).__name__}: {e}")

    # 4. Async POST 500
    try:
        r = await client.post_json_async()
    except Exception as e:
        print(f"[ERR] {type(e).__name__}: {e}")

    print(f"\nJSON-файлы ошибок: {OUTPUT_DIR}/")


if __name__ == "__main__":
    asyncio.run(main())
