// Package webug implements a web-based debug/troubleshooting/introspection
// system for the BMDB. It's optimized for use by developers and trained
// operators, prioritizing information density, fast navigation and heavy
// interlinking.
package webug

import (
	"context"
	"embed"
	"flag"
	"fmt"
	"html/template"
	"net/http"
	"regexp"
	"sync"
	"time"

	"github.com/cenkalti/backoff/v4"
	"k8s.io/klog/v2"

	"source.monogon.dev/cloud/bmaas/bmdb"
	"source.monogon.dev/cloud/bmaas/bmdb/reflection"
)

var (
	//go:embed templates/*.gohtml
	templateFS embed.FS
	templates  = template.Must(template.New("base.gohtml").Funcs(templateFuncs).ParseFS(templateFS, "templates/*"))
)

// server holds the state of an active webug interface.
type server struct {
	// connection pool to BMDB.
	conn *bmdb.Connection
	// schema retrieved from BMDB.
	schema *reflection.Schema
	// muSchema locks schema for updates.
	muSchema sync.RWMutex
}

// curSchema returns the current cached BMDB schema.
func (s *server) curSchema() *reflection.Schema {
	s.muSchema.Lock()
	defer s.muSchema.Unlock()
	return s.schema
}

// schemaWorker runs a background goroutine which attempts to update the server's
// cached BMDB schema every hour.
func (s *server) schemaWorker(ctx context.Context) {
	t := time.NewTicker(time.Hour)
	defer t.Stop()

	for {
		// Wait for the timer to tick, or for the context to expire.
		select {
		case <-ctx.Done():
			klog.Infof("Schema fetch worker exiting: %v", ctx.Err())
			return
		case <-t.C:
		}

		// Time to check the schema. Do that in an exponential backoff loop until
		// successful.
		bo := backoff.NewExponentialBackOff()
		bo.MaxElapsedTime = 0
		var schema *reflection.Schema
		err := backoff.Retry(func() error {
			var err error
			schema, err = s.conn.Reflect(ctx)
			if err != nil {
				klog.Warningf("Failed to fetch new schema: %v", err)
				return err
			}
			return nil
		}, backoff.WithContext(bo, ctx))
		// This will only happen due to context expiration.
		if err != nil {
			klog.Errorf("Giving up on schema fetch: %v", err)
			continue
		}

		// Swap the current schema if necessary.
		cur := s.curSchema().Version
		new := schema.Version
		if cur != new {
			klog.Infof("Got new schema: %s -> %s", cur, new)
			s.muSchema.Lock()
			s.schema = schema
			s.muSchema.Unlock()
		}
	}
}

// Register webug on an HTTP mux, using a BMDB connection pool.
//
// The given context will be used not only to time out the registration call, but
// also used to run a BMDB schema fetching goroutine that will attempt to fetch
// newer versions of the schema every hour.
//
// This is a low-level function useful when tying webug into an existing web
// application. If you just want to run webug on a separate port that's
// configured by flags, use Config and Config.RegisterFlags.
func Register(ctx context.Context, conn *bmdb.Connection, mux *http.ServeMux) error {
	schema, err := conn.Reflect(ctx)
	if err != nil {
		return fmt.Errorf("could not get BMDB schema for webug: %w", err)
	}
	s := server{
		conn:   conn,
		schema: schema,
	}
	go s.schemaWorker(ctx)

	type route struct {
		pattern *regexp.Regexp
		handler func(w http.ResponseWriter, r *http.Request, args ...string)
	}

	routes := []route{
		{regexp.MustCompile(`^/$`), s.viewMachines},
		{regexp.MustCompile(`^/machine/([a-fA-F0-9\-]+)$`), s.viewMachineDetail},
		{regexp.MustCompile(`^/provider/([^/]+)/([^/]+)$`), s.viewProviderRedirect},
		{regexp.MustCompile(`^/session/([^/]+)`), s.viewSession},
	}

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		for _, route := range routes {
			match := route.pattern.FindStringSubmatch(r.URL.Path)
			if match == nil {
				continue
			}
			route.handler(w, r, match[1:]...)
			return
		}
		http.NotFound(w, r)
	})
	return nil
}

// Config describes the webug interface configuration. This should be embedded
// inside your component's Config object.
//
// To configure, either set values or call RegisterFlags before flag.Parse.
//
// To run after configuration, call Start.
type Config struct {
	// If set, start a webug interface on an HTTP listener bound to the given address.
	WebugListenAddress string
}

// RegisterFlags for webug interface.
func (c *Config) RegisterFlags() {
	flag.StringVar(&c.WebugListenAddress, "webug_listen_address", "", "Address to start BMDB webug on. If not set, webug will not be started.")
}

// Start the webug interface in the foreground if enabled. The returned error
// will be either a configuration/connection error returned as soon as possible,
// or a context expiration error.
//
// The given context will be used for all connections from the webug interface to
// the given BMDB connection.
func (c *Config) Start(ctx context.Context, conn *bmdb.Connection) error {
	if c.WebugListenAddress == "" {
		return nil
	}
	mux := http.NewServeMux()
	if err := Register(ctx, conn, mux); err != nil {
		return err
	}

	klog.Infof("Webug listening at %s", c.WebugListenAddress)
	return http.ListenAndServe(c.WebugListenAddress, mux)
}
