# retoor <retoor@molodetz.nl>

import time
from datetime import datetime, timezone

import pytest
import requests

from devplacepy.database import get_table, refresh_snapshot
from tests.conftest import BASE_URL

JSON = {"Accept": "application/json"}
_counter = [0]


def _unique(prefix="wsi"):
    _counter[0] += 1
    return f"{prefix}{int(time.time() * 1000)}{_counter[0]}"


def _member():
    name = _unique()
    session = requests.Session()
    session.post(
        f"{BASE_URL}/auth/signup",
        data={
            "username": name,
            "email": f"{name}@t.dev",
            "password": "secret123",
            "confirm_password": "secret123",
            "birth_date": "1990-01-01",
            "accept_terms": "1",
        },
        allow_redirects=True,
    )
    refresh_snapshot()
    return session, name, get_table("users").find_one(username=name)


def _project(session, title, private=False):
    data = {
        "title": title,
        "description": f"Description of {title}.",
        "project_type": "software",
        "status": "In Development",
    }
    if private:
        data["is_private"] = "on"
    response = session.post(f"{BASE_URL}/projects/create", data=data, headers=JSON)
    assert response.status_code == 200, response.text
    refresh_snapshot()
    return get_table("projects").find_one(slug=response.json()["data"]["slug"])


def _publish(project, owner_uid):
    uid = _unique("wsuid")
    slug = _unique("wsslug")
    get_table("instances").insert(
        {
            "deleted_at": None,
            "deleted_by": None,
            "uid": uid,
            "project_uid": project["uid"],
            "owner_uid": owner_uid,
            "name": f"workspace {slug}",
            "slug": slug,
            "ingress_slug": slug,
            "status": "running",
            "desired_state": "running",
            "created_at": datetime.now(timezone.utc).isoformat(),
        }
    )
    refresh_snapshot()
    return uid, slug


@pytest.fixture(scope="module")
def published(app_server):
    session, name, user = _member()
    public = _project(session, f"Public {name}")
    private = _project(session, f"Private {name}", private=True)
    public_uid, public_slug = _publish(public, user["uid"])
    private_uid, private_slug = _publish(private, user["uid"])
    yield {
        "session": session,
        "user": user,
        "public": {"project": public, "uid": public_uid, "slug": public_slug},
        "private": {"project": private, "uid": private_uid, "slug": private_slug},
    }
    instances = get_table("instances")
    instances.delete(uid=public_uid)
    instances.delete(uid=private_uid)


def _entries(session=None, key=None):
    headers = dict(JSON)
    if key:
        headers["X-API-KEY"] = key
    caller = session or requests
    response = caller.get(f"{BASE_URL}/workspaces/index", headers=headers)
    assert response.status_code == 200, response.text
    return {entry["slug"]: entry for entry in response.json()["workspaces"]}


def test_the_index_is_public_and_lists_every_published_workspace(published):
    entries = _entries()
    assert published["public"]["slug"] in entries
    assert published["private"]["slug"] in entries


def test_each_row_exposes_its_uid_and_owner_uid_field(published):
    entries = _entries()
    row = entries[published["public"]["slug"]]
    assert row["uid"] == published["public"]["uid"]
    assert "owner_uid" in row


def test_a_private_projects_description_and_url_are_withheld_from_a_guest(published):
    entries = _entries()
    public_row = entries[published["public"]["slug"]]
    private_row = entries[published["private"]["slug"]]
    assert public_row["description"] == published["public"]["project"]["description"]
    assert public_row["project_url"] == f"/projects/{published['public']['project']['slug']}"
    assert private_row["description"] == ""
    assert private_row["project_url"] == ""


def test_the_owner_still_sees_their_private_projects_fields(published):
    entries = _entries(key=published["user"]["api_key"])
    private_row = entries[published["private"]["slug"]]
    assert private_row["description"] == published["private"]["project"]["description"]
    assert (
        private_row["project_url"]
        == f"/projects/{published['private']['project']['slug']}"
    )


def test_a_stranger_is_treated_like_a_guest(published):
    stranger, _, user = _member()
    entries = _entries(session=stranger, key=user["api_key"])
    assert entries[published["private"]["slug"]]["description"] == ""
    assert entries[published["private"]["slug"]]["project_url"] == ""


def test_the_table_carries_a_report_control_column(published):
    reporter, _, _ = _member()
    html = reporter.get(f"{BASE_URL}/workspaces/index").text
    assert '<th scope="col">Report</th>' in html
    assert 'data-report-type="workspace"' in html
    assert f'data-report-uid="{published["public"]["uid"]}"' in html
    assert "css/admin.css" in html
    assert 'class="admin-table"' in html
