package server

import (
	"fes/modules/ui"
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

/* performs relavent handling based on the directory passaed
 *
 * Special directories
 *  - www/     <= contains lua routes.
 *  - static/  <= static content accessable at /static/path or /static/dir/path.
 *  - include/ <= globally accessable lua functions, cannot directly access "fes" right now.
 *  - archive/ <= contains user facing files such as archives or dists.
 *
 */
func handleDir(entries []os.DirEntry, dir string, routes map[string]string, base string, isStatic bool) error {
	for _, entry := range entries {
		path := filepath.Join(dir, entry.Name())
		if entry.IsDir() {
			nextBase := joinBase(base, entry.Name())
			subEntries, err := os.ReadDir(path)
			if err != nil {
				return fmt.Errorf("failed to read directory %s: %w", path, err)
			}
			if err := handleDir(subEntries, path, routes, nextBase, isStatic); err != nil {
				return err
			}
			continue
		}
		route := joinBase(base, entry.Name())
		if !isStatic && strings.HasSuffix(entry.Name(), ".lua") {
			name := strings.TrimSuffix(entry.Name(), ".lua")
			if name == "index" {
				routes[basePath(base)] = path
				routes[route] = path
				continue
			}
			route = joinBase(base, name)
		} else if !isStatic && strings.HasSuffix(entry.Name(), ".md") {
			name := strings.TrimSuffix(entry.Name(), ".md")
			if name == "index" {
				routes[basePath(base)] = path
				routes[route] = path
				continue
			}
			route = joinBase(base, name)
		}
		routes[route] = path
	}
	return nil
}

/* helper to load all special directories */
func loadDirs() map[string]string {
	routes := make(map[string]string)

	if entries, err := os.ReadDir("www"); err == nil {
		if err := handleDir(entries, "www", routes, "", false); err != nil {
			ui.Warning("failed to handle www directory", err)
		}
	}

	if entries, err := os.ReadDir("static"); err == nil {
		if err := handleDir(entries, "static", routes, "/static", true); err != nil {
			ui.Warning("failed to handle static directory", err)
		}
	}

	if entries, err := os.ReadDir("archive"); err == nil {
		if err := handleDir(entries, "archive", routes, "/archive", true); err != nil {
			ui.Warning("failed to handle archive directory", err)
		}
	}

	return routes
}
