# retoor <retoor@molodetz.nl>

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

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


@pytest.fixture(scope="module", autouse=True)
def _settings(app_server):
    set_setting("rate_limit_per_minute", "1000000")
    set_setting("registration_open", "1")
    yield


def _signup():
    _counter_lo[0] += 1
    name = f"lo{int(time.time() * 1000)}{_counter_lo[0]}"
    requests.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 get_table("users").find_one(username=name)["api_key"]


def _h(key):
    return {"X-API-KEY": key, **JSON}


def _project(key, title):
    r = requests.post(
        f"{BASE_URL}/projects/create",
        headers=_h(key),
        data={"title": title, "description": "line ops", "project_type": "software", "status": "In Development"},
    )
    assert r.status_code == 200, r.text[:200]
    return r.json()["data"]["slug"]


def _write(key, slug, path, content):
    requests.post(
        f"{BASE_URL}/projects/{slug}/files/write",
        headers=_h(key),
        data={"path": path, "content": content},
        allow_redirects=False,
    )


def _raw(key, slug, path):
    return requests.get(
        f"{BASE_URL}/projects/{slug}/files/raw", headers=_h(key), params={"path": path}
    ).json()["content"]


@pytest.fixture
def owned():
    owner = _signup()
    other = _signup()
    slug = _project(owner, f"lineops {_counter_lo[0]}")
    _write(owner, slug, "f.txt", "a\nb\nc")
    return owner, other, slug


def test_insert_lines_non_owner_denied(owned):
    owner, other, slug = owned
    r = requests.post(
        f"{BASE_URL}/projects/{slug}/files/insert-lines",
        headers=_h(other),
        data={"path": "f.txt", "at": 1, "content": "X"},
        allow_redirects=False,
    )
    assert r.status_code == 403
    assert _raw(owner, slug, "f.txt") == "a\nb\nc"


def test_delete_lines_non_owner_denied(owned):
    owner, other, slug = owned
    r = requests.post(
        f"{BASE_URL}/projects/{slug}/files/delete-lines",
        headers=_h(other),
        data={"path": "f.txt", "start": 1, "end": 1},
        allow_redirects=False,
    )
    assert r.status_code == 403
    assert _raw(owner, slug, "f.txt") == "a\nb\nc"


def test_append_non_owner_denied(owned):
    owner, other, slug = owned
    r = requests.post(
        f"{BASE_URL}/projects/{slug}/files/append",
        headers=_h(other),
        data={"path": "f.txt", "content": "X"},
        allow_redirects=False,
    )
    assert r.status_code == 403
    assert _raw(owner, slug, "f.txt") == "a\nb\nc"


def test_append_to_missing_file_is_handled(owned):
    owner, other, slug = owned
    r = requests.post(
        f"{BASE_URL}/projects/{slug}/files/append",
        headers=_h(owner),
        data={"path": "brand_new.txt", "content": "hello"},
        allow_redirects=False,
    )
    assert r.status_code in (200, 302, 400, 404)
    assert r.status_code != 500


def test_out_of_range_line_edit_is_handled(owned):
    owner, other, slug = owned
    r = requests.post(
        f"{BASE_URL}/projects/{slug}/files/delete-lines",
        headers=_h(owner),
        data={"path": "f.txt", "start": 99, "end": 120},
        allow_redirects=False,
    )
    assert r.status_code in (200, 302, 400)
    assert r.status_code != 500
