defmodule MicrowavepropWeb.AgentSkillsControllerTest do
  use MicrowavepropWeb.ConnCase, async: true

  describe "GET /.well-known/agent-skills/index.json" do
    test "returns the agent-skills discovery index", %{conn: conn} do
      conn = get(conn, "/.well-known/agent-skills/index.json")

      assert conn.status == 200
      assert ["application/json" <> _] = get_resp_header(conn, "content-type")

      body = Jason.decode!(conn.resp_body)
      assert body["$schema"] =~ "agentskills"
      assert is_list(body["skills"])
      assert body["skills"] != []

      for skill <- body["skills"] do
        assert is_binary(skill["name"])
        assert is_binary(skill["type"])
        assert is_binary(skill["description"])
        assert is_binary(skill["url"])
        assert String.match?(skill["sha256"], ~r/^[0-9a-f]{64}$/)
      end
    end

    test "index lists at least fetch-contacts and read-algorithm", %{conn: conn} do
      conn = get(conn, "/.well-known/agent-skills/index.json")
      %{"skills" => skills} = Jason.decode!(conn.resp_body)
      names = Enum.map(skills, & &1["name"])

      assert "fetch-contacts" in names
      assert "read-algorithm" in names
    end
  end

  describe "GET /.well-known/agent-skills/:name/SKILL.md" do
    test "serves a skill document as markdown", %{conn: conn} do
      conn = get(conn, "/.well-known/agent-skills/fetch-contacts/SKILL.md")

      assert conn.status == 200
      assert ["text/markdown; charset=utf-8"] = get_resp_header(conn, "content-type")
      assert conn.resp_body =~ "Fetch contacts dataset"
    end

    test "sha256 in the index matches the served document bytes", %{conn: conn} do
      %{"skills" => skills} =
        conn |> get("/.well-known/agent-skills/index.json") |> Map.get(:resp_body) |> Jason.decode!()

      for %{"name" => name, "sha256" => expected} <- skills do
        doc = get(conn, "/.well-known/agent-skills/#{name}/SKILL.md").resp_body
        actual = :sha256 |> :crypto.hash(doc) |> Base.encode16(case: :lower)
        assert actual == expected, "sha256 mismatch for skill #{name}"
      end
    end

    test "returns 404 for unknown skill names", %{conn: conn} do
      conn = get(conn, "/.well-known/agent-skills/does-not-exist/SKILL.md")
      assert conn.status == 404
    end
  end
end
