// https://github.com/google/go-containerregistry

package main

import (
	"context"
	"flag"
	"net/url"
	"os/signal"
	"path"
	"syscall"

	"github.com/loveuer/nf/nft/log"

	"nf-repo/internal/api"
	"nf-repo/internal/interfaces"
	"nf-repo/internal/interfaces/blobs"
	"nf-repo/internal/interfaces/dbs"
	"nf-repo/internal/interfaces/manifests"
	"nf-repo/internal/interfaces/uploads"
	"nf-repo/internal/opt"
	"nf-repo/internal/tool/tools"
)

var (
	bh interfaces.BlobHandler
	uh interfaces.UploadHandler
	mh interfaces.ManifestHandler
)

func init() {
	flag.BoolVar(&opt.Cfg.Debug, "debug", false, "debug mode")
	flag.StringVar(&opt.Cfg.RepoName, "repo", "repo.me", "repo name")
	flag.StringVar(&opt.Cfg.Address, "address", "127.0.0.1:8383", "listen address")
	flag.StringVar(&opt.Cfg.DataPath, "data", "/data", "images, sqlite ... data path")
	flag.StringVar(&opt.Cfg.Proxy, "proxy", "", "proxy url")
	flag.Parse()

	tools.TablePrinter(opt.Cfg)

	var err error

	if opt.Cfg.Debug {
		log.SetLogLevel(log.LogLevelDebug)
	}

	mh = manifests.NewManifestDBHandler(dbs.Must(dbs.NewSqliteTX(path.Join(opt.Cfg.DataPath, "data.sqlite"))))
	bh = blobs.NewLocalBlobHandler(path.Join(opt.Cfg.DataPath, "layers"))
	//bh = blobs.NewS3BlobHandler(
	//	context.TODO(),
	//	"http://10.230.200.74:9000",
	//	"xWcwG0zcdR3iDXBa",
	//	"NavjSle5qQjE2rjz81hEwZW3S2fUVa66",
	//	"repo.me",
	//)
	uh = uploads.NewLocalUploader(path.Join(opt.Cfg.DataPath, "uploads"))

	if opt.Cfg.Proxy != "" {
		if opt.Proxy, err = url.Parse(opt.Cfg.Proxy); err != nil {
			log.Fatal("invalid proxy address")
		}
	}
}

func main() {
	ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	defer cancel()

	app := api.NewApi(ctx, bh, uh, mh)

	go func() {
		app.Run(opt.Cfg.Address)
	}()

	go func() {
		<-ctx.Done()
		app.Shutdown(tools.Timeout(3))
	}()

	<-ctx.Done()
	log.Warn("received quit signal...")
	<-tools.Timeout(3).Done()
}