defmodule Microwaveprop.Ionosphere.GiroClientTest do
  use ExUnit.Case, async: true

  alias Microwaveprop.Ionosphere.GiroClient

  describe "parse_tabular/1" do
    test "decodes the real Millstone Hill fixture into observation maps" do
      body = File.read!("test/fixtures/giro/mhj45_sample.txt")

      assert {:ok, rows} = GiroClient.parse_tabular(body)

      # The fixture is 2026-04-15 16:00 → 19:00 UTC at 7.5-minute cadence,
      # so 25 observations.
      assert length(rows) == 25

      first = hd(rows)
      assert first.valid_time == ~U[2026-04-15 16:00:00Z]
      assert first.confidence_score == 60
      assert_in_delta first.fo_f2_mhz, 6.856, 0.001
      assert_in_delta first.mufd_mhz, 23.63, 0.001
      # foEs was missing ("---") at 16:00.
      assert first.fo_es_mhz == nil
      assert_in_delta first.fo_e_mhz, 3.50, 0.001
      assert_in_delta first.hm_f2_km, 217.2, 0.1

      # 16:07:30 has foEs == 3.42.
      second = Enum.at(rows, 1)
      assert second.valid_time == ~U[2026-04-15 16:07:30Z]
      assert_in_delta second.fo_es_mhz, 3.42, 0.001

      last = List.last(rows)
      assert last.valid_time == ~U[2026-04-15 19:00:00Z]
      assert_in_delta last.fo_f2_mhz, 7.400, 0.001
    end

    test "returns {:ok, []} for a body with only the header" do
      body = """
      # Global Ionospheric Radio Observatory
      # Location: GEO 42.6N 288.5E, URSI-Code MHJ45 MILLSTONE HILL
      #
      #Time                     CS   foF2 QD  MUFD QD  foEs QD   foE QD   hmF2 QD
      """

      assert {:ok, []} = GiroClient.parse_tabular(body)
    end

    test "returns {:error, :no_header} when the column header is missing" do
      body = """
      # some junk
      2026-04-15T18:00:00.000Z  80  7.113 // 23.00 //
      """

      assert {:error, :no_header} = GiroClient.parse_tabular(body)
    end

    test "skips data lines whose token count doesn't match the header" do
      # Header declares 5 value columns (10 tokens after time+CS) but the
      # data row is truncated. Should be skipped rather than crashing.
      body = """
      #Time                     CS   foF2 QD  MUFD QD  foEs QD   foE QD   hmF2 QD
      2026-04-15T18:00:00.000Z  80  7.113 //
      2026-04-15T18:07:30.000Z  80  7.088 // 22.76 //  3.35 //  3.13 //  246.0 //
      """

      assert {:ok, [row]} = GiroClient.parse_tabular(body)
      assert row.valid_time == ~U[2026-04-15 18:07:30Z]
    end
  end
end
