# -*- coding: utf-8 -*-
"""账号↔端口多身份：登录返回身份列表、选择身份签发新令牌、按身份访问。"""
from __future__ import annotations

from fastapi.testclient import TestClient


def login(client: TestClient, username: str, password: str = "123456") -> dict:
    res = client.post("/auth/login", json={"username": username, "password": password})
    assert res.status_code == 200, res.text
    return res.json()


def auth(token: str) -> dict:
    return {"Authorization": f"Bearer {token}"}


def test_single_identity_auto_login(client):
    """单身份账号（opc01）登录即绑定该身份，可直接访问对应端口。"""
    body = login(client, "opc01")
    assert len(body["identities"]) == 1
    assert body["identities"][0]["port"] == "opc"
    assert body["role"] == "opc_member"
    assert body.get("identity_id") == body["identities"][0]["id"]

    res = client.get("/opc/dashboard", headers=auth(body["token"]))
    assert res.status_code == 200, res.text


def test_multi_identity_login_returns_all_and_neutral(client):
    """多身份账号（ent01：企业 + OPC）登录返回全部身份，令牌为中性（回退单角色）。"""
    body = login(client, "ent01")
    ports = [i["port"] for i in body["identities"]]
    assert "enterprise" in ports and "opc" in ports

    # 中性令牌按 users.role 回退为 enterprise：访问 OPC 端口应 403
    res = client.get("/opc/dashboard", headers=auth(body["token"]))
    assert res.status_code == 403


def test_select_identity_grants_opc_access(client):
    """选择 OPC 身份后，新令牌可访问 OPC 端口，且 /me 反映该身份。"""
    body = login(client, "ent01")
    opc_identity = next(i for i in body["identities"] if i["port"] == "opc")

    res = client.post(
        "/auth/select-identity",
        headers=auth(body["token"]),
        json={"identity_id": opc_identity["id"]},
    )
    assert res.status_code == 200, res.text
    selected = res.json()
    assert selected["role"] == "opc_member"
    assert selected["identity_id"] == opc_identity["id"]

    dash = client.get("/opc/dashboard", headers=auth(selected["token"]))
    assert dash.status_code == 200, dash.text

    me = client.get("/auth/me", headers=auth(selected["token"])).json()
    assert me["role"] == "opc_member"
    assert me.get("port") == "opc"


def test_select_identity_rejects_other_users_identity(client):
    """不能选择不属于当前账号的身份。"""
    body = login(client, "opc01")
    other = "ident_ent01_opc"  # 属于 ent01 的身份 id
    res = client.post(
        "/auth/select-identity",
        headers=auth(body["token"]),
        json={"identity_id": other},
    )
    assert res.status_code == 404
