# derived from FSE's SupSlashB policy
# thanks again to @p for hinting me on is_admin/is_moderator
# if you were a fine sharp knife, I'll start killing people with you just to put you to a good use

defmodule Pleroma.Web.ActivityPub.MRF.JannyLog do
	require Logger
	alias Pleroma.User
	alias Pleroma.Config
	@behaviour Pleroma.Web.ActivityPub.MRF.Policy

	@impl true
	def filter(
		%{
			"type" => "Create",
			"actor" => actor,
			"to" => mto,
			"cc" => mcc,
			"object" => %{
				"type" => "Note",
				"summary" => "janny log",
				"to" => oto,
				"cc" => occ,
			} = object
		} = message
	) do
		actor_info = URI.parse(actor)
		user = User.get_cached_by_ap_id(actor)
		domain = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :host])
		proto = Pleroma.Config.get([Pleroma.Web.Endpoint, :url, :scheme])
		janny = proto <> "://" <> domain <> "/users/" <> Pleroma.Config.get([:mrf_janny_log, :log_user])

		if(actor_info.host == domain && (user.is_admin || user.is_moderator)) do
			afol = "#{actor}/followers"
			Logger.warn("janny log #{inspect(message)}")
			# There's probably a better way to do this in Elixir, but...
			# "When in doubt, use brute force." -- Ken Thompson
			object =
				object
				|> Map.put("summary", domain <> " janny action log, posted by @" <> user.nickname)
				|> Map.put("actor", janny)
				|> Map.put("to",
					Enum.map(oto, fn
						i when i == afol -> janny <> "/followers"
						i -> i
					end))
				|> Map.put("cc",
					Enum.map(occ, fn
						i when i == afol -> janny <> "/followers"
						i -> i
					end))

			message =
				message
				|> Map.put("actor", janny)
				|> Map.put("object", object)
				|> Map.put("to",
					Enum.map(mto, fn
						i when i == afol -> janny <> "/followers"
						i -> i
					end))
				|> Map.put("cc",
					Enum.map(mcc, fn
						i when i == afol -> janny <> "/followers"
						i -> i
					end))

			Logger.warn("janny log NEW MESSAGE:  #{inspect(message)}")

			{:ok, message}
		else
			{:ok, message}
		end
	end

	@impl true
	def filter(message), do: {:ok, message}
  @impl true
  def describe, do: {:ok, %{}}
end
