package middleware

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

	"github.com/gin-gonic/gin"
)

func init() {
	gin.SetMode(gin.TestMode)
}

func TestInternalAuthMiddleware_AllowAnonymous_Allows(t *testing.T) {
	t.Parallel()

	r := gin.New()
	r.Use(InternalAuthMiddleware("secret-token", true))
	r.GET("/internal/test", func(c *gin.Context) {
		c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/internal/test", nil)
	// No X-Internal-Token header
	rr := httptest.NewRecorder()
	r.ServeHTTP(rr, req)

	if rr.Code != http.StatusOK {
		t.Fatalf("expected 200 when allow_anonymous=true, got %d body=%s", rr.Code, rr.Body.String())
	}
}

func TestInternalAuthMiddleware_TokenRequired_NoToken_Returns401(t *testing.T) {
	t.Parallel()

	r := gin.New()
	r.Use(InternalAuthMiddleware("secret-token", false))
	r.GET("/internal/test", func(c *gin.Context) {
		c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/internal/test", nil)
	// No X-Internal-Token header
	rr := httptest.NewRecorder()
	r.ServeHTTP(rr, req)

	if rr.Code != http.StatusUnauthorized {
		t.Fatalf("expected 401 when token required but missing, got %d", rr.Code)
	}
}

func TestInternalAuthMiddleware_TokenRequired_ValidToken_Returns200(t *testing.T) {
	t.Parallel()

	r := gin.New()
	r.Use(InternalAuthMiddleware("secret-token", false))
	r.GET("/internal/test", func(c *gin.Context) {
		c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/internal/test", nil)
	req.Header.Set("X-Internal-Token", "secret-token")
	rr := httptest.NewRecorder()
	r.ServeHTTP(rr, req)

	if rr.Code != http.StatusOK {
		t.Fatalf("expected 200 with valid token, got %d body=%s", rr.Code, rr.Body.String())
	}
}

func TestInternalAuthMiddleware_TokenRequired_InvalidToken_Returns401(t *testing.T) {
	t.Parallel()

	r := gin.New()
	r.Use(InternalAuthMiddleware("secret-token", false))
	r.GET("/internal/test", func(c *gin.Context) {
		c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/internal/test", nil)
	req.Header.Set("X-Internal-Token", "wrong-token")
	rr := httptest.NewRecorder()
	r.ServeHTTP(rr, req)

	if rr.Code != http.StatusUnauthorized {
		t.Fatalf("expected 401 with wrong token, got %d", rr.Code)
	}
}

func TestInternalAuthMiddleware_EmptyTokenNotAnonymous_Returns401(t *testing.T) {
	t.Parallel()

	r := gin.New()
	// Empty token and not allowing anonymous
	r.Use(InternalAuthMiddleware("", false))
	r.GET("/internal/test", func(c *gin.Context) {
		c.String(http.StatusOK, "ok")
	})

	req := httptest.NewRequest(http.MethodGet, "/internal/test", nil)
	rr := httptest.NewRecorder()
	r.ServeHTTP(rr, req)

	if rr.Code != http.StatusUnauthorized {
		t.Fatalf("expected 401 when token empty and not anonymous, got %d body=%s", rr.Code, rr.Body.String())
	}
}
