# retoor <retoor@molodetz.nl>

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

JSON_edit = {"Accept": "application/json"}
_counter_edit = [0]


def _session_edit():
    _counter_edit[0] += 1
    name = f"cmtedit{int(time.time() * 1000)}{_counter_edit[0]}"
    s = requests.Session()
    s.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,
    )
    return s, name


def _create_post_edit(session, title):
    r = session.post(
        f"{BASE_URL}/posts/create",
        data={"content": "Post for comment edit.", "title": title, "topic": "devlog"},
        allow_redirects=False,
    )
    slug = r.headers["location"].split("/posts/")[-1]
    return get_table("posts").find_one(slug=slug)["uid"]


def _create_comment_edit(session, post_uid, content="Original body"):
    session.post(
        f"{BASE_URL}/comments/create",
        data={
            "content": content,
            "target_type": "post",
            "post_uid": post_uid,
            "target_uid": post_uid,
        },
        allow_redirects=False,
    )
    refresh_snapshot()
    return get_table("comments").find_one(target_uid=post_uid)


def test_edit_own_comment_json(app_server):
    s, _ = _session_edit()
    post_uid = _create_post_edit(s, f"edit-json-{int(time.time() * 1000)}")
    comment = _create_comment_edit(s, post_uid)
    r = s.post(
        f"{BASE_URL}/comments/edit/{comment['uid']}",
        headers=JSON_edit,
        data={"content": "Edited body text"},
    )
    assert r.status_code == 200, r.text[:300]
    body = r.json()
    assert body["uid"] == comment["uid"]
    assert body["content"] == "Edited body text"
    assert f"#comment-{comment['uid']}" in body["url"]
    assert body["updated_at"]
    refresh_snapshot()
    stored = get_table("comments").find_one(uid=comment["uid"])
    assert stored["content"] == "Edited body text"


def test_edit_comment_no_js_redirects(app_server):
    s, _ = _session_edit()
    post_uid = _create_post_edit(s, f"edit-nojs-{int(time.time() * 1000)}")
    comment = _create_comment_edit(s, post_uid)
    r = s.post(
        f"{BASE_URL}/comments/edit/{comment['uid']}",
        data={"content": "No JS edited body"},
        allow_redirects=False,
    )
    assert r.status_code in (302, 303)
    assert f"#comment-{comment['uid']}" in r.headers["location"]
    refresh_snapshot()
    assert get_table("comments").find_one(uid=comment["uid"])["content"] == "No JS edited body"


def test_edit_comment_requires_owner(app_server):
    owner, _ = _session_edit()
    post_uid = _create_post_edit(owner, f"edit-owner-{int(time.time() * 1000)}")
    comment = _create_comment_edit(owner, post_uid, "Owner body")
    other, _ = _session_edit()
    r = other.post(
        f"{BASE_URL}/comments/edit/{comment['uid']}",
        headers=JSON_edit,
        data={"content": "Hijacked body"},
    )
    assert r.status_code == 403
    refresh_snapshot()
    assert get_table("comments").find_one(uid=comment["uid"])["content"] == "Owner body"


def test_edit_comment_requires_login(app_server):
    owner, _ = _session_edit()
    post_uid = _create_post_edit(owner, f"edit-anon-{int(time.time() * 1000)}")
    comment = _create_comment_edit(owner, post_uid, "Guarded body")
    anon = requests.Session()
    r = anon.post(
        f"{BASE_URL}/comments/edit/{comment['uid']}",
        data={"content": "Anon body"},
        allow_redirects=False,
    )
    assert r.status_code == 303
    refresh_snapshot()
    assert get_table("comments").find_one(uid=comment["uid"])["content"] == "Guarded body"


def test_edit_comment_too_short_rejected(app_server):
    s, _ = _session_edit()
    post_uid = _create_post_edit(s, f"edit-short-{int(time.time() * 1000)}")
    comment = _create_comment_edit(s, post_uid, "Long enough body")
    r = s.post(
        f"{BASE_URL}/comments/edit/{comment['uid']}",
        headers=JSON_edit,
        data={"content": "ab"},
        allow_redirects=False,
    )
    assert r.status_code in (400, 422)
    refresh_snapshot()
    assert get_table("comments").find_one(uid=comment["uid"])["content"] == "Long enough body"
