package main

// This program emulates the meta data server in GCE and is intended to be used in the Skolo.
// It is derived from infra/skolo/go/metadata_server and designed to run in Kubernetes (but that
// is not strictly necessary).
// It also incorporates the functionality of skolo/go/get_oauth2_token, uniting the fetching
// and serving the oauth tokens in a single process.

import (
	"context"
	"flag"
	"fmt"
	"net/http"

	"github.com/go-chi/chi/v5"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/skolo/go/skmetadata"
)

const (
	// APP_NAME is the name of this app.
	APP_NAME = "metadata_server"
)

type instanceMetadataMap map[string]map[string]string

func (m instanceMetadataMap) Get(instance, key string) (string, error) {
	rv, ok := m[instance][key]
	if !ok {
		return "", fmt.Errorf("Unknown instance or key.")
	}
	return rv, nil
}

type projectMetadataMap map[string]string

func (m projectMetadataMap) Get(key string) (string, error) {
	rv, ok := m[key]
	if !ok {
		return "", fmt.Errorf("Unknown key.")
	}
	return rv, nil
}

func main() {
	// Flags.
	var (
		port     = flag.String("port", ":8000", "HTTP service port for the web server (e.g., ':8000')")
		promPort = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':10110')")
		confFile = flag.String("conf", "", "Configuration file that defines which tokens should be served.")
	)

	common.InitWithMust(
		APP_NAME,
		common.PrometheusOpt(promPort),
	)

	// TODO(borenet): Load these from a file?
	var pm projectMetadataMap = map[string]string{
		"mykey": "myvalue",
	}
	var im instanceMetadataMap = map[string]map[string]string{
		"inst": {
			"mykey2": "myvalue2",
		},
	}

	// Read the config file.
	configs, err := readConfigFile(*confFile)
	if err != nil {
		sklog.Fatalf("Error reading config file %q: %s", *confFile, err)
	}

	// svcAccountTokens maps [token_file][ServiceAccountToken] and ensures there is one instance
	// of ServiceAccountToken per token file. That instance is responsible for refreshing it.
	svcAccountTokens := make(map[string]*skmetadata.ServiceAccountToken, len(configs))

	// clientTokenMapping maps [ip | host_name | self] ServiceAccountToken.
	clientTokenMapping := make(map[string]*skmetadata.ServiceAccountToken, len(configs))
	for _, config := range configs {
		token, ok := svcAccountTokens[config.KeyFile]
		if !ok {
			token, err = skmetadata.NewServiceAccountToken(config.KeyFile, true)
			if err != nil {
				sklog.Fatalf("Error retrieving service account token: %s", err)
			}

			// Start the update loop as a background process.
			go token.UpdateLoop(context.Background())
			svcAccountTokens[config.KeyFile] = token
		}

		// Create one entry per client which is an IP address, a hostname or 'self'.
		for _, clientAddr := range config.Clients {
			clientTokenMapping[clientAddr] = token
		}
	}

	r := chi.NewRouter()
	skmetadata.SetupServer(r, pm, im, clientTokenMapping)
	http.Handle("/", httputils.LoggingGzipRequestResponse(r))
	sklog.Infof("Ready to serve on http://localhost%s", *port)
	sklog.Fatal(http.ListenAndServe(*port, nil))
}
