# typed: false
require "rails_helper"

unless defined?(Rack::MiniProfiler)
  class Rack::MiniProfiler
    def self.step(name)
      yield
    end
  end
end

RSpec.describe BlobEntriesController, type: :controller do
  render_views

  let(:blob_file) do
    create(
      :blob_file,
      content_type: "image/jpeg",
      contents:
        File.read(
          Rails.root.join("app/assets/images/domain-icons/inkbunny.png"),
        ),
    )
  end
  let(:sha256_hex) { HexUtil.bin2hex(blob_file.sha256) }

  describe "GET #show" do
    context "with plain text content" do
      let(:blob_file) do
        create(:blob_file, content_type: "text/plain", contents: "Hello World")
      end

      it "renders content as plain text" do
        get :show, params: { sha256: sha256_hex }
        expect(response).to have_http_status(:success)
        expect(response.body).to eq("Hello World")
        expect(response.content_type).to eq("text/plain")
      end
    end

    context "with HTML content" do
      let(:blob_file) do
        create(:blob_file, content_type: "text/html", contents: "<p>Hello</p>")
      end

      it "renders content as HTML" do
        get :show, params: { sha256: sha256_hex }
        expect(response).to have_http_status(:success)
        expect(response.body).to include("<p>Hello</p>")
        expect(response.content_type).to eq("text/html")
      end
    end

    context "with json content" do
      let(:blob_file) do
        create(
          :blob_file,
          content_type: "application/json",
          contents: '{"hello":"world"}',
        )
      end

      it "renders json as json" do
        get :show, params: { sha256: sha256_hex }
        expect(response).to have_http_status(:success)
        expect(response.body).to include("hello")
        expect(response.content_type).to eq("application/json")
      end
    end

    context "with image content" do
      it "sends data with correct headers" do
        get :show, params: { sha256: sha256_hex }
        expect(response).to have_http_status(:success)
        expect(response.content_type).to eq("image/jpeg")
        expect(response.headers["Content-Disposition"]).to include("inline")
        expect(response.body).not_to be_nil
      end

      context "with thumbnail request" do
        it "generates thumbnail for valid size" do
          get :show, params: { sha256: sha256_hex, thumb: "tiny" }
          expect(response).to have_http_status(:success)
          expect(response.content_type).to eq("image/jpeg")
          expect(response.headers["Content-Disposition"]).to include("inline")
          expect(response.body).to_not be_nil
        end

        it "raises error for invalid thumb size" do
          expect {
            get :show, params: { sha256: sha256_hex, thumb: "invalid" }
          }.to raise_error(/invalid thumb/)
        end
      end
    end

    context "png that has a gif extension and content type" do
      let(:blob_file) do
        create(
          :blob_file,
          content_type: "image/gif",
          contents:
            File.read(
              Rails.root.join("test/fixtures/files/images/fa.24326406.gif"),
            ),
        )
      end

      it "renders the image as a gif" do
        get :show,
            params: {
              sha256: sha256_hex,
              thumb: "content-container",
              format: "gif",
            }
        expect(response).to have_http_status(:success)
        expect(response.content_type).to eq("image/jpeg")
        expect(response.headers["Content-Disposition"]).to include("inline")
        expect(response.body).to_not be_nil
      end
    end

    it "sets cache headers" do
      get :show, params: { sha256: sha256_hex }
      expect(response.headers["Expires"]).to be_present
      expect(response.headers["Cache-Control"]).to include("public")
    end

    it "handles ETags" do
      get :show, params: { sha256: sha256_hex }
      etag = response.headers["ETag"]
      expect(etag).to be_present

      # Subsequent request with same ETag should return not modified
      request.headers["If-None-Match"] = etag
      get :show, params: { sha256: sha256_hex }
      expect(response).to have_http_status(:not_modified)
    end
  end
end
