package frontend

import (
	"net/http/httptest"
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	"github.com/grafana/grafana/pkg/setting"
	"github.com/grafana/grafana/pkg/web"
)

// setupTestWebAssets creates a temporary directory with test assets manifest
func setupTestWebAssets(tb testing.TB) string {
	tb.Helper()

	publicDir := tb.TempDir()
	tb.Cleanup(func() { _ = os.RemoveAll(publicDir) })

	// Create build directory
	buildDir := filepath.Join(publicDir, "build")
	err := os.MkdirAll(buildDir, 0750)
	require.NoError(tb, err)

	// Create test assets manifest
	manifest := `{
		"entrypoints": {
			"app": {
				"assets": {
					"js": [
						"public/build/runtime.js",
						"public/build/app.js"
					],
					"css": ["public/build/grafana.app.css"]
				}
			},
			"swagger": {
				"assets": {
					"js": ["public/build/runtime.js", "public/build/swagger.js"],
					"css": ["public/build/grafana.swagger.css"]
				}
			},
			"dark": {
				"assets": {
					"css": ["public/build/grafana.dark.css"]
				}
			},
			"light": {
				"assets": {
					"css": ["public/build/grafana.light.css"]
				}
			}
		},
		"runtime.js": {
			"src": "public/build/runtime.js",
			"integrity": "sha256-test123"
		},
		"app.js": {
			"src": "public/build/app.js",
			"integrity": "sha256-test456"
		}
	}`

	err = os.WriteFile(filepath.Join(buildDir, "assets-manifest.json"), []byte(manifest), 0644)
	require.NoError(tb, err)

	return publicDir
}

func TestFrontendService_WebAssets(t *testing.T) {
	t.Run("should serve index with proper assets", func(t *testing.T) {
		publicDir := setupTestWebAssets(t)
		cfg := &setting.Cfg{
			HTTPPort:       "3000",
			StaticRootPath: publicDir,
			Env:            setting.Dev, // needs to be dev to bypass the cache
		}
		service := createTestService(t, cfg)

		mux := web.New()
		service.addMiddlewares(mux)
		service.registerRoutes(mux)

		// Test index route which should load web assets
		req := httptest.NewRequest("GET", "/", nil)
		recorder := httptest.NewRecorder()

		mux.ServeHTTP(recorder, req)

		assert.Equal(t, 200, recorder.Code)
		assert.Contains(t, recorder.Header().Get("Content-Type"), "text/html")
		assert.Contains(t, recorder.Header().Get("Cache-Control"), "no-store")

		// The response should contain references to the assets
		body := recorder.Body.String()
		assert.Contains(t, body, "src=\"public/build/runtime.js\" type=\"text/javascript\"")
		assert.Contains(t, body, "src=\"public/build/app.js\" type=\"text/javascript\"")
	})
}
