package main

import (
	"context"
	"flag"
	"fmt"
	"net/http"
	"os"
	"os/signal"
	"regexp"
	"strings"
	"syscall"
	"time"

	"bsm/full/all/internal/config"
	"bsm/full/all/internal/impl"
	allserver "bsm/full/all/internal/server"
	"bsm/full/all/internal/service"
)

var ServiceKey = "default"

var workspacePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$`)

func normalizeWorkspace(value string) (string, error) {
	value = strings.ToLower(strings.TrimSpace(value))
	if !workspacePattern.MatchString(value) {
		return "", fmt.Errorf("workspace must match %s", workspacePattern.String())
	}
	return value, nil
}

func main() {
	workspace := flag.String("workspace", ServiceKey, "workspace used to select etc/{workspace}_{runtime}.yaml")
	flag.Parse()
	value, err := normalizeWorkspace(*workspace)
	if err != nil {
		panic(err)
	}
	ServiceKey = value

	config.New(ServiceKey)
	impl.NewImpl()

	srv := allserver.New()
	if err := service.Expose(srv); err != nil {
		panic(err)
	}

	stop := make(chan os.Signal, 1)
	signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		<-stop
		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()
		_ = srv.Stop(ctx)
	}()

	if err := srv.Start(config.Spec.Addr); err != nil && err != http.ErrServerClosed {
		panic(err)
	}
}
