defmodule Mix.Tasks.Aprs.ParseFileTest do
  use ExUnit.Case, async: false

  alias Mix.Tasks.Aprs.ParseFile

  @tmp_dir System.tmp_dir!()

  setup do
    input = Path.join(@tmp_dir, "aprs_parse_file_input_#{System.unique_integer([:positive])}.txt")
    output = Path.join(@tmp_dir, "aprs_parse_file_output_#{System.unique_integer([:positive])}.txt")

    on_exit(fn ->
      File.rm(input)
      File.rm(output)
    end)

    %{input: input, output: output}
  end

  test "skips blank and comment lines and writes failed lines to the output", %{
    input: input,
    output: output
  } do
    File.write!(input, """
    # a comment

    N0CALL>APRS:this is not a valid packet at all
    """)

    # Mix tasks emit output via Mix.shell; silence it during the test.
    Mix.shell(Mix.Shell.Process)
    ParseFile.run([input, "--output", output])

    assert File.exists?(output)
    contents = File.read!(output)

    # The garbage line should be written; comments and blank lines should not.
    refute contents =~ "# a comment"
    # The parser may or may not accept the "not a valid packet" line depending
    # on its lenience — but if anything is written, it's that one line.
    case String.trim(contents) do
      "" -> :ok
      line -> assert line == "N0CALL>APRS:this is not a valid packet at all"
    end

    assert_received {:mix_shell, :info, [msg]}
    assert msg =~ "Processed"
  end

  test "errors and exits when input file is missing", %{output: output} do
    Mix.shell(Mix.Shell.Process)

    missing = Path.join(@tmp_dir, "does_not_exist_#{System.unique_integer([:positive])}.txt")

    try do
      ParseFile.run([missing, "--output", output])
      flunk("expected run to exit")
    catch
      :exit, {:shutdown, 1} -> :ok
    end

    assert_received {:mix_shell, :error, [err]}
    assert err =~ "input file not found"
  end
end
