package main

import (
	"flag"
	"log"
	"net/http"
	"os"

	restful "github.com/emicklei/go-restful"
	swaggerui "github.com/mcluseau/go-swagger-ui"
	"m.cluseau.fr/go/watchable/streamsse"

	dlshtml "novit.tech/direktil/local-server/html"
	"novit.tech/direktil/local-server/pkg/apiutils"
)

const (
	etcDir = "/etc/direktil"
)

var (
	Version = "dev"
	Date    = "now"
)

var (
	address    = flag.String("address", ":7606", "HTTP listen address")
	tlsAddress = flag.String("tls-address", "", "HTTPS listen address")
	certFile   = flag.String("tls-cert", etcDir+"/server.crt", "Server TLS certificate")
	keyFile    = flag.String("tls-key", etcDir+"/server.key", "Server TLS key")

	autoUnlock = flag.String("auto-unlock", "", "Auto-unlock store (testing only!) env: DLS_AUTO_UNLOCK")
)

func main() {
	log.SetFlags(log.LstdFlags | log.Lshortfile)

	flag.Parse()

	if *address == "" && *tlsAddress == "" {
		log.Fatal("no listen address given")
	}

	log.Print("Direktil local-server version ", Version, " (", Date, ")")
	wPublicState.Change(func(s *PublicState) { s.ServerVersion = Version })

	computeUIHash()

	openSecretStore()

	{
		autoUnlock := *autoUnlock
		if autoUnlock == "" {
			autoUnlock = os.Getenv("DLS_AUTO_UNLOCK")
		}
		if autoUnlock != "" {
			log.Printf("auto-unlocking the store")
			err := unlockSecretStore("test", []byte(autoUnlock))
			if err.Any() {
				log.Fatal(err)
			}

			log.Print("store auto-unlocked")
		}

		os.Setenv("DLS_AUTO_UNLOCK", "")
	}

	apiutils.Setup(func() {
		registerWS(restful.DefaultContainer)
	})

	swaggerui.HandleAt("/swagger-ui/")

	staticHandler := http.FileServer(http.FS(dlshtml.FS))
	http.Handle("/favicon.ico", staticHandler)
	http.Handle("/ui/", staticHandler)
	http.Handle("/dist/", http.StripPrefix("/dist/", upstreamServer{}))

	http.Handle("/public-state", streamsse.StreamHandler(wPublicState))
	http.Handle("/state", requireAdmin(streamsse.StreamHandler(wState)))

	if *address != "" {
		log.Print("HTTP listening on ", *address)
		go log.Fatal(http.ListenAndServe(*address, nil))
	}

	if *tlsAddress != "" {
		log.Print("HTTPS listening on ", *tlsAddress)
		go log.Fatal(http.ListenAndServeTLS(*tlsAddress, *certFile, *keyFile, nil))
	}

	select {}
}
