from __future__ import annotations

import base64
import json

from app_server_harness import AppServerHarness

from openai_codex import Codex, CodexConfig
from openai_codex.generated.v2_all import (
    ChatgptAuthTokensLoginAccountParams,
    LoginAccountParams,
)


def _app_server_config(harness: AppServerHarness) -> CodexConfig:
    """Build an isolated login config without inheriting ambient API-key auth."""
    config = harness.app_server_config()
    config.env = {**(config.env or {}), "OPENAI_API_KEY": ""}
    return config


def test_api_key_login_authenticates_follow_up_model_requests(tmp_path) -> None:
    """API-key login should authorize the next Responses request with that key."""
    with AppServerHarness(tmp_path, requires_openai_auth=True) as harness:
        harness.responses.enqueue_assistant_message("api key auth", response_id="api-key-auth")

        with Codex(config=_app_server_config(harness)) as codex:
            codex.login_api_key("sk-sdk-login-test")
            result = codex.thread_start().run("prove api key auth")
            request = harness.responses.single_request()

    assert {
        "final_response": result.final_response,
        "authorization": request.header("authorization"),
    } == {
        "final_response": "api key auth",
        "authorization": "Bearer sk-sdk-login-test",
    }


def test_chatgpt_token_login_authenticates_follow_up_model_requests(tmp_path) -> None:
    """ChatGPT token handoff should authorize later Responses requests with that token."""
    account_id = "workspace-sdk-chatgpt"

    def _encode(payload: dict[str, object]) -> str:
        raw = json.dumps(payload, separators=(",", ":"), sort_keys=True).encode("utf-8")
        return base64.urlsafe_b64encode(raw).rstrip(b"=").decode("ascii")

    # App-server parses claims from the access token before persisting external ChatGPT auth.
    header = _encode({"alg": "none", "typ": "JWT"})
    claims = _encode(
        {
            "email": "sdk-chatgpt@example.com",
            "https://api.openai.com/auth": {
                "chatgpt_account_id": account_id,
                "chatgpt_plan_type": "pro",
            },
        }
    )
    access_token = f"{header}.{claims}.sig"

    with AppServerHarness(tmp_path, requires_openai_auth=True) as harness:
        harness.responses.enqueue_assistant_message(
            "chatgpt token auth",
            response_id="chatgpt-token-auth",
        )

        with Codex(config=_app_server_config(harness)) as codex:
            login = codex._client.account_login_start(
                LoginAccountParams(
                    root=ChatgptAuthTokensLoginAccountParams(
                        access_token=access_token,
                        chatgpt_account_id=account_id,
                        chatgpt_plan_type="pro",
                        type="chatgptAuthTokens",
                    )
                )
            )
            result = codex.thread_start().run("prove chatgpt token auth")
            request = harness.responses.single_request()

    assert {
        "login_type": login.root.type,
        "final_response": result.final_response,
        "authorization": request.header("authorization"),
    } == {
        "login_type": "chatgptAuthTokens",
        "final_response": "chatgpt token auth",
        "authorization": f"Bearer {access_token}",
    }
