package middleware

import (
	"io"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestGzipCompressesEligibleResponses(t *testing.T) {
	handler := Gzip(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Length", "11")
		_, _ = io.WriteString(w, "hello world")
	}))

	request := httptest.NewRequest(http.MethodGet, "/page", nil)
	request.Header.Set("Accept-Encoding", "gzip")
	response := httptest.NewRecorder()

	handler.ServeHTTP(response, request)

	if got := response.Header().Get("Content-Encoding"); got != "gzip" {
		t.Fatalf("Content-Encoding = %q, want gzip", got)
	}
	if got := response.Header().Get("Content-Length"); got != "" {
		t.Fatalf("Content-Length = %q, want empty for gzipped response", got)
	}
	if got := response.Header().Get("Vary"); got != "Accept-Encoding" {
		t.Fatalf("Vary = %q, want Accept-Encoding", got)
	}
}

func TestGzipSkipsRangeAndHeadRequests(t *testing.T) {
	handler := Gzip(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, _ = io.WriteString(w, "hello world")
	}))

	tests := []struct {
		name        string
		method      string
		rangeHeader string
	}{
		{name: "range", method: http.MethodGet, rangeHeader: "bytes=0-4"},
		{name: "head", method: http.MethodHead},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			request := httptest.NewRequest(tt.method, "/asset.css", nil)
			request.Header.Set("Accept-Encoding", "gzip")
			if tt.rangeHeader != "" {
				request.Header.Set("Range", tt.rangeHeader)
			}
			response := httptest.NewRecorder()

			handler.ServeHTTP(response, request)

			if got := response.Header().Get("Content-Encoding"); got != "" {
				t.Fatalf("Content-Encoding = %q, want empty", got)
			}
		})
	}
}
