defmodule TarakanWeb.API.FindingController do
  @moduledoc """
  Public read access to disclosed findings.

  Anonymous reads pass through the same disclosure policy as the finding page
  (`Scans.get_finding/2` with a nil scope): restricted or summary-only reviews
  answer 404, never a redacted body.
  """
  use TarakanWeb, :controller

  alias Tarakan.Scans

  def show(conn, %{"public_id" => public_id}) do
    case Scans.get_finding(nil, public_id) do
      {:ok, {scan, finding}} ->
        json(conn, %{finding: finding_json(scan, finding)})

      {:error, :not_found} ->
        conn
        |> put_status(:not_found)
        |> json(%{error: "finding was not found or is not public"})
    end
  end

  defp finding_json(scan, finding) do
    canonical = finding.canonical_finding
    repository = scan.repository

    %{
      public_id: finding.public_id,
      title: (canonical && canonical.title) || finding.title,
      severity: finding.severity,
      status: (canonical && canonical.status) || "open",
      description: (canonical && canonical.description) || finding.description,
      reproduction_steps: canonical && canonical.reproduction_steps,
      affected_versions: canonical && canonical.affected_versions,
      cwe_id: canonical && canonical.cwe_id,
      cve_id: canonical && canonical.cve_id,
      file_path: finding.file_path,
      line_start: finding.line_start,
      line_end: finding.line_end,
      first_seen_commit_sha: canonical && canonical.first_seen_commit_sha,
      last_seen_commit_sha: canonical && canonical.last_seen_commit_sha,
      verified_at: canonical && canonical.verified_at,
      vendor_notified_at: canonical && canonical.vendor_notified_at,
      counters: %{
        detections_count: (canonical && canonical.detections_count) || 0,
        distinct_submitters_count: (canonical && canonical.distinct_submitters_count) || 0,
        distinct_models_count: (canonical && canonical.distinct_models_count) || 0,
        confirmations_count: (canonical && canonical.confirmations_count) || 0,
        disputes_count: (canonical && canonical.disputes_count) || 0
      },
      repository: %{
        host: repository.host,
        owner: repository.owner,
        name: repository.name
      },
      record_url: TarakanWeb.Endpoint.url() <> ~p"/findings/#{finding.public_id}",
      inserted_at: finding.inserted_at
    }
  end
end
