package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os/user"
	"path/filepath"
	"strings"

	"git-browser/internal/repository"
	"git-browser/internal/web"
)

func main() {
	sshUser := flag.String("ssh-user", "git", "SSH user allowed to access repositories")
	root := flag.String("root", "repos", "repository root relative to the SSH user's home directory")
	listen := flag.String("listen", ":8080", "HTTP listen address")
	flag.Parse()

	resolvedRoot, cloneRoot, err := resolveRoot(*sshUser, *root)
	if err != nil {
		log.Fatalf("resolve repository root: %v", err)
	}

	store, err := repository.Discover(resolvedRoot)
	if err != nil {
		log.Fatalf("discover repositories: %v", err)
	}

	server, err := web.NewServer(store, web.Config{
		SSHUser:   *sshUser,
		CloneRoot: cloneRoot,
	})
	if err != nil {
		log.Fatalf("create server: %v", err)
	}

	log.Printf("serving %s on %s", store.Root(), *listen)
	if err := http.ListenAndServe(*listen, server.Handler()); err != nil {
		log.Fatal(err)
	}
}

func resolveRoot(userName, root string) (string, string, error) {
	account, err := user.Lookup(userName)
	if err != nil {
		return "", "", err
	}

	cleaned := filepath.Clean(root)
	if root == "" || cleaned == "." {
		return account.HomeDir, "", nil
	}
	if filepath.IsAbs(cleaned) || cleaned == ".." || strings.HasPrefix(cleaned, ".."+string(filepath.Separator)) {
		return "", "", fmt.Errorf("root must stay within %s's home directory", userName)
	}

	return filepath.Join(account.HomeDir, cleaned), filepath.ToSlash(cleaned), nil
}