package http

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"io/fs"
	"net/http"

	"source.toby3d.me/toby3d/home/internal/domain"
	"source.toby3d.me/toby3d/home/internal/resource"
)

type Handler struct {
	contentDir fs.FS
	resources  resource.UseCase
}

func NewHandler(resources resource.UseCase, contentDir fs.FS) *Handler {
	return &Handler{
		contentDir: contentDir,
		resources:  resources,
	}
}

func (h *Handler) Handle(ctx context.Context, path string) (http.Handler, error) {
	res, err := h.resources.Do(ctx, path)
	if err != nil {
		return nil, err
	}

	file, err := h.contentDir.Open(res.File.Filename())
	if err != nil {
		return nil, fmt.Errorf("cannot open resource: %w", err)
	}
	defer file.Close()

	resBytes, err := io.ReadAll(file)
	if err != nil {
		return nil, fmt.Errorf("cannot read resource: %w", err)
	}

	// TODO(toby3d): ugly workaround, refactor that.
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		http.ServeContent(w, r, res.Name(), domain.ResourceModTime(res), bytes.NewReader(resBytes))
	}), nil
}
