# retoor <retoor@molodetz.nl>

import json

import requests

from tests.api.quizzes._helpers import (
    DOCUMENT,
    JSON,
    build_published,
    create_quiz,
    import_quiz,
    signup,
)
from tests.conftest import BASE_URL


def test_importing_requires_auth(app_server, seeded_db):
    response = requests.post(
        f"{BASE_URL}/quizzes/import", data={"document": json.dumps(DOCUMENT)}, headers=JSON
    )
    assert response.status_code in (401, 303)


def test_importing_creates_a_complete_draft(app_server, seeded_db):
    session, _ = signup()
    response = import_quiz(session)
    assert response.status_code == 200
    data = response.json()["data"]
    assert data["question_count"] == 2
    assert data["url"].endswith("/edit")


def test_an_imported_quiz_has_its_questions(app_server, seeded_db):
    session, _ = signup()
    slug = import_quiz(session).json()["data"]["slug"]
    payload = session.get(f"{BASE_URL}/quizzes/{slug}/edit", headers=JSON).json()
    assert [question["kind"] for question in payload["questions"]] == [
        "single_choice",
        "numeric",
    ]
    assert payload["quiz"]["total_points"] == 3


def test_an_imported_quiz_carries_its_settings(app_server, seeded_db):
    session, _ = signup()
    slug = import_quiz(session).json()["data"]["slug"]
    quiz = session.get(f"{BASE_URL}/quizzes/{slug}", headers=JSON).json()["quiz"]
    assert quiz["pass_percent"] == 60
    assert quiz["reveal_answers"] is True


def test_an_imported_quiz_starts_as_a_draft(app_server, seeded_db):
    session, _ = signup()
    slug = import_quiz(session).json()["data"]["slug"]
    quiz = session.get(f"{BASE_URL}/quizzes/{slug}", headers=JSON).json()["quiz"]
    assert quiz["status"] == "draft"


def test_an_imported_quiz_passes_validation(app_server, seeded_db):
    session, _ = signup()
    slug = import_quiz(session).json()["data"]["slug"]
    payload = session.get(f"{BASE_URL}/quizzes/{slug}/edit", headers=JSON).json()
    assert payload["validation_errors"] == []


def test_an_imported_quiz_can_be_published(app_server, seeded_db):
    session, _ = signup()
    slug = import_quiz(session).json()["data"]["slug"]
    response = session.post(f"{BASE_URL}/quizzes/{slug}/publish", headers=JSON)
    assert response.status_code == 200


def test_invalid_json_is_rejected(app_server, seeded_db):
    session, _ = signup()
    response = session.post(
        f"{BASE_URL}/quizzes/import", data={"document": "{not json"}, headers=JSON
    )
    assert response.status_code == 422


def test_a_document_without_questions_is_rejected(app_server, seeded_db):
    session, _ = signup()
    response = import_quiz(session, {"title": "Empty document", "questions": []})
    assert response.status_code == 422


def test_a_broken_question_is_rejected(app_server, seeded_db):
    session, _ = signup()
    document = {
        "title": "Broken document",
        "questions": [{"kind": "single_choice", "prompt": "q", "options": [{"label": "only"}]}],
    }
    assert import_quiz(session, document).status_code == 422


def test_an_oversized_document_is_rejected(app_server, seeded_db):
    from devplacepy.config import QUIZ_MAX_QUESTIONS

    session, _ = signup()
    question = {"kind": "numeric", "prompt": "q", "numeric_value": 1}
    document = {"title": "Huge document", "questions": [question] * (QUIZ_MAX_QUESTIONS + 1)}
    assert import_quiz(session, document).status_code == 422


def test_an_unknown_kind_is_rejected(app_server, seeded_db):
    session, _ = signup()
    document = {"title": "Weird document", "questions": [{"kind": "telepathy", "prompt": "q"}]}
    assert import_quiz(session, document).status_code == 422


def test_the_public_export_omits_the_answer_key(app_server, seeded_db):
    session, _ = signup()
    slug = build_published(session, title="Export withhold quiz")
    payload = requests.get(f"{BASE_URL}/quizzes/{slug}/export", headers=JSON).json()
    choice = payload["questions"][0]
    assert all("is_correct" not in option for option in choice["options"])
    assert "correct_boolean" not in choice
    assert "numeric_value" not in payload["questions"][1]


def test_the_public_export_keeps_the_prompts(app_server, seeded_db):
    session, _ = signup()
    slug = build_published(session, title="Export prompts quiz")
    payload = requests.get(f"{BASE_URL}/quizzes/{slug}/export", headers=JSON).json()
    assert payload["questions"][0]["prompt"].startswith("Which journal mode")
    assert [option["label"] for option in payload["questions"][0]["options"]] == [
        "DELETE",
        "WAL",
        "MEMORY",
    ]


def test_the_owner_export_carries_the_answer_key(app_server, seeded_db):
    session, _ = signup()
    slug = build_published(session, title="Owner export quiz")
    payload = session.get(f"{BASE_URL}/quizzes/{slug}/export", headers=JSON).json()
    assert any(option.get("is_correct") for option in payload["questions"][0]["options"])
    assert payload["questions"][1]["numeric_value"] == 1024.0


def test_another_member_gets_the_public_export(app_server, seeded_db):
    owner, _ = signup()
    slug = build_published(owner, title="Other export quiz")
    other, _ = signup()
    payload = other.get(f"{BASE_URL}/quizzes/{slug}/export", headers=JSON).json()
    assert all("is_correct" not in option for option in payload["questions"][0]["options"])


def test_a_draft_export_is_hidden_from_a_guest(app_server, seeded_db):
    session, _ = signup()
    slug = create_quiz(session, "Hidden export quiz")
    assert requests.get(f"{BASE_URL}/quizzes/{slug}/export", headers=JSON).status_code == 404


def test_an_export_round_trips_back_through_import(app_server, seeded_db):
    session, _ = signup()
    slug = build_published(session, title="Round trip quiz")
    exported = session.get(f"{BASE_URL}/quizzes/{slug}/export", headers=JSON).json()
    reimported = import_quiz(session, exported)
    assert reimported.status_code == 200
    new_slug = reimported.json()["data"]["slug"]
    assert session.get(f"{BASE_URL}/quizzes/{new_slug}/export", headers=JSON).json() == exported


def test_the_export_carries_the_settings(app_server, seeded_db):
    session, _ = signup()
    slug = build_published(session, title="Export settings quiz", pass_percent="75")
    payload = requests.get(f"{BASE_URL}/quizzes/{slug}/export", headers=JSON).json()
    assert payload["settings"]["pass_percent"] == 75
