defmodule TarakanWeb.API.LeaderboardControllerTest do
  use TarakanWeb.ConnCase

  setup do
    submitter = github_account_fixture()
    repository = listed_github_repository_fixture(submitter)

    repository
    |> scan_fixture(submitter, %{"findings_json" => findings_json_fixture(1)})
    |> publish_scan("public")

    %{submitter: submitter}
  end

  test "returns ranked rows", %{conn: conn, submitter: submitter} do
    conn = get(conn, ~p"/api/leaderboard")

    assert %{"leaderboard" => rows} = json_response(conn, 200)
    assert row = Enum.find(rows, &(&1["handle"] == submitter.handle))
    assert row["rank"] == 1
    assert row["reputation"]["total"] > 0
    assert is_map(row["stats"])
    assert row["slashed_stakes"] == 0
    assert row["profile_url"] == TarakanWeb.Endpoint.url() <> "/" <> submitter.handle
  end

  test "whitelists sort, severity, and window params", %{conn: conn} do
    conn = get(conn, ~p"/api/leaderboard?sort=reviews&severity=high&window=7")
    assert %{"leaderboard" => _} = json_response(conn, 200)

    conn = get(conn, ~p"/api/leaderboard?sort=bogus&severity=bogus&window=bogus")
    assert %{"leaderboard" => _} = json_response(conn, 200)
  end

  defp publish_scan(scan, visibility) do
    scan = confirmation_fixture(scan, reviewer_account_fixture())
    scan = confirmation_fixture(scan, reviewer_account_fixture())

    scope = Tarakan.Accounts.Scope.for_account(moderator_account_fixture())

    if visibility == "public" do
      scan.repository
      |> Tarakan.Repositories.Repository.participation_changeset(%{
        participation_mode: "maintainer_verified"
      })
      |> Tarakan.Repo.update!()
    end

    {:ok, scan} =
      Tarakan.Scans.accept_scan(scope, scan, %{
        "moderation_reason" => "evidence_reviewed",
        "moderation_notes" =>
          "Two independent reviewers supplied reproducible evidence for the pinned commit."
      })

    {:ok, scan} =
      Tarakan.Scans.update_visibility(scope, scan, visibility, %{
        "moderation_reason" => "disclosure_reviewed",
        "moderation_notes" =>
          "Disclosure was separately reviewed for scope, secrets, and personal data.",
        "sensitive_data_reviewed" => "true"
      })

    scan
  end
end
