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

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

OUTPUT_DIR = "output/test_curl_cffi"

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

validator_auth = (
    ResponseValidator()
    .when_all(status_code_is(429), raise_as=Exceptions.Auth.RateLimit)
    .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):
        return curl_requests.get("https://httpbin.org/status/200", verify=False)

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

    @request_logging(save_errors_to_file=True, errors_output_dir=OUTPUT_DIR)
    @validate_response(validator=validator_auth)
    async def get_429_async(self):
        async with AsyncSession(verify=False) as session:
            return await session.get("https://httpbin.org/status/429")

    @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 AsyncSession(verify=False) as session:
            return await session.post(
                "https://httpbin.org/status/500",
                json={"key": "value", "action": "test"},
            )


async def main():
    client = ApiClient()
    print("=== curl_cffi ===\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 429 → RateLimit
    try:
        r = await client.get_429_async()
    except Exceptions.Auth.RateLimit 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())
