defmodule BerrypodWeb.Plugs.BrokenUrlTracker do
  @moduledoc """
  Wraps the router to record 404s in the broken URLs table.

  Works in dev mode too — Plug.Debugger intercepts exceptions before
  error templates render, so we catch NoRouteError here, record it,
  then re-raise so the normal error handling continues.
  """

  @behaviour Plug

  def init(opts) do
    router = Keyword.fetch!(opts, :router)
    router_opts = router.init([])
    {router, router_opts}
  end

  def call(conn, {router, router_opts}) do
    router.call(conn, router_opts)
  rescue
    e in [Phoenix.Router.NoRouteError, BerrypodWeb.NotFoundError] ->
      unless static_path?(conn.request_path) do
        prior_hits = Berrypod.Analytics.count_pageviews_for_path(conn.request_path)
        Berrypod.Redirects.record_broken_url(conn.request_path, prior_hits)

        if prior_hits > 0 do
          Berrypod.Redirects.attempt_auto_resolve(conn.request_path)
        end
      end

      reraise e, __STACKTRACE__
  end

  defp static_path?(path) do
    String.starts_with?(path, "/assets/") or
      String.starts_with?(path, "/images/") or
      String.starts_with?(path, "/image_cache/") or
      String.starts_with?(path, "/mockups/") or
      String.starts_with?(path, "/favicon")
  end
end
