package main

import (
	_ "embed"
	"errors"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"os"
	"strings"
)

//go:embed public/index.html
var indexSrc string

const PORT = 3000
const IMAGES_DIR = "images"

var cachedImages []string

func loadImages() error {
	imagesDir := fmt.Sprintf("public/%s", IMAGES_DIR)

	entries, err := os.ReadDir(imagesDir)
	if err != nil {
		return fmt.Errorf("ERROR: Failed to read public/%s directory: %w", IMAGES_DIR, err)
	}

	cachedImages = []string{}

	for _, entry := range entries {
		if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".webp") {
			cachedImages = append(cachedImages, entry.Name())
		}
	}

	fmt.Printf("OK: Loaded %d images\n", len(cachedImages))
	return nil
}

func getPage(w http.ResponseWriter, r *http.Request) {
	imageName := cachedImages[rand.Intn(len(cachedImages))]
	imageURL := fmt.Sprintf("/%s/%s", IMAGES_DIR, imageName)
	src := strings.Replace(indexSrc, "{{ IMAGE_URL }}", imageURL, 1)

	io.WriteString(w, src)
}

func getFavicon(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, "public/favicon.ico")
}

func main() {
	if err := loadImages(); err != nil {
		fmt.Printf("ERROR: Error loading images: %s\n", err)
		os.Exit(1)
	}

	if len(cachedImages) == 0 {
		fmt.Printf("ERROR: no images found in public/%s\n", IMAGES_DIR)
		os.Exit(1)
	}

	http.HandleFunc("/", getPage)
	http.HandleFunc("/favicon.ico", getFavicon)
	http.Handle(fmt.Sprintf("/%s/", IMAGES_DIR), http.StripPrefix(fmt.Sprintf("/%s/", IMAGES_DIR), http.FileServer(http.Dir(fmt.Sprintf("public/%s", IMAGES_DIR)))))

	fmt.Printf("OK: Listening on port %d\n", PORT)
	err := http.ListenAndServe(fmt.Sprintf(":%d", PORT), nil)
	if errors.Is(err, http.ErrServerClosed) {
		fmt.Printf("OK: Server closed\n")
	} else if err != nil {
		fmt.Printf("ERROR: error starting server: %s\n", err)
		os.Exit(1)
	}
}
