defmodule Towerops.LogFilter do
  @moduledoc """
  Filters out noisy log messages from external sources like port scanners and bots.
  """

  @doc """
  Filters out Bandit HTTP errors from invalid requests.

  This suppresses errors from:
  - HTTP/0.9 requests (very old protocol, typically port scanners)
  - Malformed HTTP requests from bots
  - Invalid protocol versions

  These errors are expected when running a public-facing server and don't
  indicate application problems.
  """
  def filter_bandit_errors(log_event, _opts) do
    case log_event do
      # Filter Bandit.HTTPError with Invalid HTTP version
      %{level: :error, msg: {:string, msg}} when is_binary(msg) ->
        filter_string_message(msg)

      # Filter other Bandit connection errors
      %{level: :error, msg: {:report, %{label: {:error_logger, :error_report}, report: report}}} ->
        filter_error_report(report)

      # Don't filter anything else
      _ ->
        :ignore
    end
  end

  defp filter_string_message(msg) do
    if bandit_invalid_http_error?(msg), do: :stop, else: :ignore
  end

  defp filter_error_report(message: msg) when is_binary(msg) do
    if String.contains?(msg, "Bandit.HTTPError"), do: :stop, else: :ignore
  end

  defp filter_error_report(_), do: :ignore

  defp bandit_invalid_http_error?(msg) do
    String.contains?(msg, "Bandit.HTTPError") and String.contains?(msg, "Invalid HTTP version")
  end
end
