# typed: true
# frozen_string_literal: true
class Admin::ProxyController < ApplicationController
  before_action :authenticate_user!
  before_action :require_admin!
  skip_before_action :verify_authenticity_token, only: %i[grafana prometheus]

  def grafana
    fullpath =
      "http://grafana:3100#{request.fullpath.delete_prefix("/grafana")}"
    proxy_response(fullpath, "/grafana")
  end

  def prometheus
    fullpath = "http://prometheus:9090#{request.fullpath.delete_prefix("/prometheus")}"
    proxy_response(fullpath, "/prometheus")
  end

  private

  def require_admin!
    unless current_user&.admin?
      redirect_to root_path, alert: "You are not authorized to access this area"
    end
  end

  def grafana_proxy_headers
    { "X-WEBAUTH-USER" => "admin" }.merge(proxy_headers)
  end

  def proxy_headers
    {
      "X-Forwarded-Host" => request.host_with_port,
      "X-Forwarded-Proto" => request.ssl? ? "https" : "http",
      "X-Forwarded-For" => request.remote_ip,
      "Host" => request.host,
      "Connection" => request.headers["Connection"],
      "Upgrade" => request.headers["Upgrade"],
      "Accept" => request.headers["Accept"],
      "Cookie" => request.headers["Cookie"],
      "Content-Type" => request.headers["Content-Type"],
      "Content-Length" => request.headers["Content-Length"],
    }.merge
  end

  def websocket_request?
      request.headers["Connection"]&.include?("upgrade")
  end

  def proxy_response(fullpath, prefix)
    method = request.method.downcase.to_s
    if method == "post"
      response = HTTP.headers(grafana_proxy_headers).send(method, fullpath, body: request.raw_post)
    else
      response = HTTP.headers(grafana_proxy_headers).send(method, fullpath)
    end

    headers = response.headers.to_h

    # Handle redirects by rewriting the Location header
    if response.code.in?([301, 302, 303, 307, 308]) &&
         headers["Location"].present?
      location = headers["Location"]
      # Strip the host from absolute URLs
      location = location.gsub(%r{^https?://[^/]+}, "")
      # Add our prefix to relative URLs
      location = "#{prefix}#{location}" if location.start_with?("/")
      headers["Location"] = location
    end

    # Pass through the response with all headers
    response_headers = headers.except("Content-Type")

    render_args = {
      body: response.body.to_s,
      status: response.code,
      content_type: headers["Content-Type"],
      headers: response_headers,
    }
    render_args[:location] = headers["Location"] if headers["Location"]

    render render_args
  end
end
