# frozen_string_literal: true

require "aws-sdk-s3"

module Recordings
  # Serve file replay/thumbnail al browser senza esporre URL S3 interni (es. http://garage:3900).
  class ServeFromStorage
    def initialize(key:, content_type:, disposition: "inline", filename: nil)
      @key = key
      @content_type = content_type
      @disposition = disposition
      @filename = filename
    end

    def call(controller)
      path = local_path
      return controller.send_file(path, type: @content_type, disposition: @disposition, filename: @filename) if path

      proxy_s3(controller)
    end

    def local_path
      path = Recordings::Storage.new.local_path_for_key(@key)
      path if path && File.exist?(path)
    end

    private

    def proxy_s3(controller)
      raise ArgumentError, "Storage key mancante" if @key.blank?
      raise ArgumentError, "Storage S3 non configurato" if MatchLiveTv.replay_storage_local?

      range = controller.request.headers["Range"]
      resp = s3_client.get_object(
        bucket: MatchLiveTv.replay_storage_bucket,
        key: @key,
        range: range.presence
      )

      controller.response.headers["Content-Type"] = @content_type
      controller.response.headers["Accept-Ranges"] = "bytes"
      controller.response.headers["Content-Length"] = resp.content_length.to_s if resp.content_length
      controller.response.headers["Content-Range"] = resp.content_range if resp.content_range.present?

      data = resp.body.read
      max = 1.gigabyte
      raise ArgumentError, "File troppo grande per il proxy" if data.bytesize > max

      if @disposition == "attachment" && @filename.present?
        controller.send_data(
          data,
          type: @content_type,
          disposition: "attachment",
          filename: @filename
        )
      else
        controller.send_data(data, type: @content_type, disposition: "inline")
      end
      controller.status = :partial_content if range.present? && resp.content_range.present?
    end

    def s3_client
      @s3_client ||= Aws::S3::Client.new(
        access_key_id: MatchLiveTv.replay_storage_access_key_id,
        secret_access_key: MatchLiveTv.replay_storage_secret_access_key,
        endpoint: MatchLiveTv.replay_storage_endpoint,
        region: MatchLiveTv.replay_storage_region,
        force_path_style: MatchLiveTv.replay_storage_force_path_style?,
        # Garage non sempre allinea i checksum AWS su Range/read parziali
        response_checksum_validation: "WHEN_REQUIRED"
      )
    end
  end
end
