#!/usr/bin/env python3
# Covers frontend role UI behavior for the multi-tenant/RBAC plan: admin/user
# login, admin-only navigation affordances, user inability to access admin
# resource management routes, and absence of global-shared controls for users.

import os
import sys


try:
    from playwright.sync_api import expect, sync_playwright
except ImportError:
    print("SKIP: Playwright is not installed; run after installing frontend test dependencies")
    sys.exit(77)


FRONTEND_URL = os.environ.get("FRONTEND_URL", "http://localhost:18080")
ADMIN_USER = os.environ.get("ADMIN_USER", os.environ.get("BOOTSTRAP_ADMIN_USER", "admin"))
ADMIN_PASS = os.environ.get("ADMIN_PASS", os.environ.get("BOOTSTRAP_ADMIN_PASS", ""))
USER_A = os.environ.get("USER_A", "")
USER_A_PASS = os.environ.get("USER_A_PASS", "")


def require_env(name: str, value: str) -> None:
    if not value:
        print(f"SKIP: {name} is required for role UI contract checks")
        sys.exit(77)


def login(page, username: str, password: str) -> None:
    page.goto(FRONTEND_URL, wait_until="networkidle")
    assert "Register" not in page.locator("body").inner_text(timeout=10000), "login page must not expose public registration"
    if page.locator("input[type='password']").count() == 0:
        page.evaluate("localStorage.clear()")
        page.goto(FRONTEND_URL, wait_until="networkidle")
    text_inputs = page.locator("input:not([type='password'])")
    expect(text_inputs.first).to_be_visible(timeout=10000)
    text_inputs.first.fill(username)
    page.locator("input[type='password']").first.fill(password)
    page.get_by_role("button").filter(has_text="Login").last.click()
    page.wait_for_url("**/home", timeout=15000)
    page.wait_for_load_state("networkidle")
    expect(page.locator("body")).not_to_contain_text("Login failed")


def visible_text(page) -> str:
    return page.locator("body").inner_text(timeout=10000)


def assert_user_restrictions(page) -> None:
    body = visible_text(page).lower()
    forbidden_labels = [
        "global shared",
        "global_shared",
        "make shared",
        "all workspaces",
        "admin console",
        "user management",
        "workspace management",
    ]
    found = [label for label in forbidden_labels if label in body]
    assert not found, f"user UI exposes admin/global controls: {found}"

    admin_paths = [
        "/admin",
        "/admin/users",
        "/admin/workspaces",
        "/configuration/users",
        "/configuration/workspaces",
    ]
    for path in admin_paths:
        page.goto(FRONTEND_URL.rstrip("/") + path, wait_until="networkidle")
        page.wait_for_timeout(500)
        text = visible_text(page).lower()
        assert "forbidden" in text or "unauthorized" in text or page.url.rstrip("/") != FRONTEND_URL.rstrip("/") + path, (
            f"user can access admin route {path}"
        )


def assert_admin_affordances(page) -> None:
    page.goto(FRONTEND_URL.rstrip("/") + "/configuration/clusters", wait_until="networkidle")
    page.wait_for_load_state("networkidle")
    text = visible_text(page).lower()
    expected_any = ["cluster", "registry", "workspace", "user", "admin"]
    assert any(item in text for item in expected_any), "admin UI did not render management affordances"
    page.goto(FRONTEND_URL.rstrip("/") + "/configuration/users", wait_until="networkidle")
    page.wait_for_load_state("networkidle")
    text = visible_text(page).lower()
    assert "create user" in text and "accounts" in text, "admin user management UI did not render"
    if USER_A:
        row = page.locator("tr").filter(has_text=USER_A).first
        expect(row).to_be_visible(timeout=10000)
        delete_button = row.get_by_role("button", name="Delete")
        expect(delete_button).to_be_visible(timeout=5000)
        box = delete_button.bounding_box()
        viewport = page.viewport_size or {"width": 1440, "height": 950}
        assert box and 0 <= box["x"] <= viewport["width"] - box["width"], "Delete User button is outside the visible viewport"


require_env("ADMIN_PASS or BOOTSTRAP_ADMIN_PASS", ADMIN_PASS)
require_env("USER_A", USER_A)
require_env("USER_A_PASS", USER_A_PASS)

with sync_playwright() as p:
    browser = p.chromium.launch(headless=True)

    admin_page = browser.new_page(viewport={"width": 1440, "height": 950})
    login(admin_page, ADMIN_USER, ADMIN_PASS)
    assert_admin_affordances(admin_page)

    user_page = browser.new_page(viewport={"width": 1440, "height": 950})
    login(user_page, USER_A, USER_A_PASS)
    assert_user_restrictions(user_page)

    browser.close()

print("PASS: multi-tenant/RBAC UI contract")
