package main

{{- if $.Imports }}

import (
	{{- range $import := $.Imports }}
	{{$import.Name}} "{{$import.Path}}"
	{{- end }}
)
{{- end }}

func main() {
	os.Exit(run(context.Background(), os.Args[1:]...))
}

// Run the cli
func run(ctx context.Context, args ...string) int {
	if err := parse(ctx, args...); err != nil {
		if errors.Is(err, context.Canceled) {
			return 0
		}
		console.Error(err.Error())
		return 1
	}
	return 0
}

// Parse the arguments
func parse(ctx context.Context, args ...string) error {
	cli := commander.New("bud")
	app := new(App)
	cli.Flag("listen", "address to listen to").String(&app.Listen).Default(":3000")
	cli.Flag("log", "filter logs with a pattern").Short('L').String(&app.Log).Default("info")
	cli.Run(app.Run)
	return cli.Parse(ctx, args)
}

// App command
type App struct {
	Listen string
	Log string
}

// logger creates a structured log that supports filtering
func (a *App) logger() (log.Log, error) {
	level, err := log.ParseLevel(a.Log)
	if err != nil {
		return nil, err
	}
	return log.New(levelfilter.New(console.New(os.Stderr), level)), nil
}

// Run your app
func (a *App) Run(ctx context.Context) error {
	log, err := a.logger()
	if err != nil {
		return err
	}
	budClient, err := budhttp.Try(log, os.Getenv("BUD_DEV_URL"))
	if err != nil {
		return err
	}
	{{- if $.Provider.Variable "github.com/livebud/bud/package/remotefs.*Client" }}
	remoteClient, err := remotefs.Dial(ctx, os.Getenv("BUD_AFS_URL"))
	if err != nil {
		return err
	}
	{{- end }}
	{{- if $.Provider.Variable "github.com/livebud/bud/package/gomod.*Module" }}
	// Load the module dependency
	{{- if $.Flag.Embed }}
	module, err := gomod.Parse("go.mod", []byte("module e"))
	if err != nil {
		return err
	}
	{{- else }}
	module, err := gomod.Find(".")
	if err != nil {
		return err
	}
	{{- end }}
	{{- end }}
	// Load the web server
	webServer, err := loadWeb(
		{{/* Order matters. Ordered by package name (e.g. budhttp > context) */}}
		{{- if $.Provider.Variable "github.com/livebud/bud/package/budhttp.Client" }}budClient,{{ end }}
		{{- if $.Provider.Variable "context.Context" }}ctx,{{ end }}
		{{- if $.Provider.Variable "github.com/livebud/bud/package/gomod.*Module" }}module,{{ end }}
		{{- if $.Provider.Variable "github.com/livebud/bud/package/log.Log" }}log,{{ end }}
		{{- if $.Provider.Variable "github.com/livebud/bud/package/remotefs.*Client" }}remoteClient,{{ end }}
	)
	if err != nil {
		budClient.Publish("app:error", []byte(err.Error()))
		return err
	}
	// Inform bud that we're ready
	budClient.Publish("app:ready", nil)
	// Start serving requests
	log.Debug("app: listening on %s", a.Listen)
	return webServer.Serve(ctx, a.Listen)
}

{{ $.Provider.Function }}