defmodule Towerops.LoggerFiltersTest do
  use ExUnit.Case, async: true

  alias Towerops.LoggerFilters

  describe "drop_oban_shutdown/2" do
    test "stops Oban source shutdown messages" do
      log_event = %{
        meta: %{source: :oban},
        msg: {:string, "Received unexpected message: {:EXIT, #PID<0.123.0>, :shutdown}"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :stop
    end

    test "stops Oban queue shutdown messages with error_logger tag" do
      log_event = %{
        meta: %{error_logger: %{tag: :error_msg}},
        msg:
          {:string,
           "Oban.Queue.Watchman #PID<0.456.0> received unexpected message in handle_info/2: {:EXIT, #PID<0.789.0>, :shutdown}"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :stop
    end

    test "stops Oban plugins shutdown messages" do
      log_event = %{
        meta: %{error_logger: %{tag: :error_msg}},
        msg: {:string, "Oban.Plugins.Pruner received unexpected message: {:EXIT, #PID<0.123.0>, :shutdown}"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :stop
    end

    test "ignores non-Oban messages" do
      log_event = %{
        meta: %{},
        msg: {:string, "Some regular log message"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores Oban messages without shutdown" do
      log_event = %{
        meta: %{source: :oban},
        msg: {:string, "Some normal Oban message"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores Oban messages with EXIT but no shutdown" do
      log_event = %{
        meta: %{source: :oban},
        msg: {:string, "Received unexpected message: {:EXIT, #PID<0.123.0>, :normal}"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores messages with only EXIT keyword" do
      log_event = %{
        meta: %{source: :oban},
        msg: {:string, "EXIT without shutdown"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores messages with only shutdown keyword" do
      log_event = %{
        meta: %{source: :oban},
        msg: {:string, "Graceful shutdown"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores Oban queue messages without EXIT" do
      log_event = %{
        meta: %{error_logger: %{tag: :error_msg}},
        msg: {:string, "Oban.Queue.Watchman received unexpected message: :some_message"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores Oban queue messages without shutdown" do
      log_event = %{
        meta: %{error_logger: %{tag: :error_msg}},
        msg: {:string, "Oban.Queue.Watchman received unexpected message: {:EXIT, #PID<0.123.0>, :normal}"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores log events with missing meta fields" do
      log_event = %{
        msg: {:string, "Some message"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores log events with non-string messages" do
      log_event = %{
        meta: %{source: :oban},
        msg: {:report, %{some: :data}}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "ignores log events with wrong error_logger tag" do
      log_event = %{
        meta: %{error_logger: %{tag: :info}},
        msg: {:string, "Oban.Queue.Watchman received unexpected message: {:EXIT, #PID<0.123.0>, :shutdown}"}
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "handles nil message gracefully" do
      log_event = %{
        meta: %{source: :oban},
        msg: nil
      }

      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
    end

    test "passes through opts parameter unchanged" do
      log_event = %{
        meta: %{},
        msg: {:string, "Some message"}
      }

      # Verify opts parameter doesn't affect the result
      assert LoggerFilters.drop_oban_shutdown(log_event, []) == :ignore
      assert LoggerFilters.drop_oban_shutdown(log_event, some: :option) == :ignore
      assert LoggerFilters.drop_oban_shutdown(log_event, %{key: "value"}) == :ignore
    end
  end

  describe "drop_shutdown_errors/2" do
    test "stops port_died log messages" do
      log_event = %{
        msg: {:string, "Erlang error: {:port_died, :normal}"}
      }

      assert LoggerFilters.drop_shutdown_errors(log_event, []) == :stop
    end

    test "stops write_failed with epipe log messages" do
      log_event = %{
        msg: {:string, "{:write_failed, :standard_io, :enoent, {:no_translation, :unicode, :latin1}} {:device, :epipe}"}
      }

      assert LoggerFilters.drop_shutdown_errors(log_event, []) == :stop
    end

    test "ignores write_failed without epipe" do
      log_event = %{
        msg: {:string, "{:write_failed, :standard_io, :enoent}"}
      }

      assert LoggerFilters.drop_shutdown_errors(log_event, []) == :ignore
    end

    test "ignores normal log messages" do
      log_event = %{
        msg: {:string, "Some regular log message"}
      }

      assert LoggerFilters.drop_shutdown_errors(log_event, []) == :ignore
    end

    test "ignores non-string log messages" do
      log_event = %{
        msg: {:report, %{some: :data}}
      }

      assert LoggerFilters.drop_shutdown_errors(log_event, []) == :ignore
    end

    test "ignores log events with nil message" do
      log_event = %{msg: nil}

      assert LoggerFilters.drop_shutdown_errors(log_event, []) == :ignore
    end
  end
end
