package main

import (
	"context"
	"encoding/json"
	"net/http"
	"path/filepath"
	"regexp"
	"strings"
	"text/template"
	"time"

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/storage"
	"github.com/cenkalti/backoff/v4"
	"github.com/go-chi/chi/v5"
	"github.com/unrolled/secure"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/option"

	"go.skia.org/infra/codesize/go/bloaty"
	"go.skia.org/infra/codesize/go/codesizeserver/rpc"
	"go.skia.org/infra/codesize/go/store"
	"go.skia.org/infra/go/baseapp"
	"go.skia.org/infra/go/fileutil"
	"go.skia.org/infra/go/gcs/gcsclient"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/now"
	"go.skia.org/infra/go/pubsub/sub"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
)

const (
	gcpProjectName = "skia-public"
	gcsBucket      = "skia-codesize"
	pubSubTopic    = "skia-codesize-files"

	// numMostRecentBinaries is the number of most recent binaries to show on the index page (grouped
	// by changelist or patchset).
	numMostRecentBinaries = 20

	// Preload the last 10 days (arbitrarily chosen) worth of data. Past that is probably not
	// relevant to most developers, and loading too much data can make the server take a long
	// time to load.
	daysToPreload = 10

	// Some sections (e.g. .text) have a lot of children. This groups them up beyond a certain
	// point to help the treemap not be too hard to read or slow to render.
	maxChildrenPerParent = 200
)

var exponentialBackoffSettings = &backoff.ExponentialBackOff{
	InitialInterval:     5 * time.Second,
	RandomizationFactor: 0.5,
	Multiplier:          2,
	MaxInterval:         time.Minute,
	MaxElapsedTime:      5 * time.Minute,
	Clock:               backoff.SystemClock,
}

// gcsPubSubEvent is the payload of the PubSub events sent by GCS on file uploads. See
// https://cloud.google.com/storage/docs/json_api/v1/objects#resource-representations.
type gcsPubSubEvent struct {
	// Bucket name, e.g. "skia-codesize".
	Bucket string `json:"bucket"`
	// Name of the affected file (relative to the bucket), e.g. "foo/bar/baz.txt".
	Name string `json:"name"`
}

type server struct {
	templates *template.Template
	gcsClient *gcsclient.StorageClient
	store     store.Store
}

// See baseapp.Constructor.
func new() (baseapp.App, error) {
	ctx := context.Background()
	srv := &server{}

	// Set up GCS client.
	ts, err := google.DefaultTokenSource(ctx, storage.ScopeReadWrite)
	if err != nil {
		return nil, skerr.Wrapf(err, "failed to get token source")
	}
	client := httputils.DefaultClientConfig().WithTokenSource(ts).With2xxOnly().Client()
	storageClient, err := storage.NewClient(ctx, option.WithHTTPClient(client))
	if err != nil {
		return nil, skerr.Wrapf(err, "failed to create storage client")
	}
	srv.gcsClient = gcsclient.New(storageClient, gcsBucket)

	// Set up Store.
	s := store.New(func(ctx context.Context, path string) ([]byte, error) {
		sklog.Infof("Downloading %s from GCS", path)

		var contents []byte
		downloadFunc := func() error {
			contents, err = srv.gcsClient.GetFileContents(ctx, path)
			return err
		}
		if err := backoff.Retry(downloadFunc, exponentialBackoffSettings); err != nil {
			return nil, skerr.Wrapf(err, "even with exponential backoff, could not download %s", path)
		}

		return contents, nil
	})
	srv.store = s

	// Preload the latest Bloaty outputs.
	if err := srv.preloadBloatyFiles(ctx); err != nil {
		return nil, skerr.Wrapf(err, "failed to preload Bloaty outputs from GCS")
	}

	// Subscribe to the PubSub topic via which GCS will notify us of file uploads. We use a broadcast
	// name provider to ensure that all replicas are notified of each file upload. We specify an
	// expiration policy to shorten the time until unused subscriptions are garbage-collected after
	// redeploying the service.
	expirationPolicy := time.Hour * 24 * 7
	subscription, err := sub.NewWithSubNameProviderAndExpirationPolicy(ctx, gcpProjectName, pubSubTopic, sub.NewBroadcastNameProvider(*baseapp.Local, pubSubTopic), &expirationPolicy, 1)
	if err != nil {
		return nil, skerr.Wrapf(err, "failed to subscribe to PubSub topic")
	}

	// Launch a goroutine to listen for PubSub messages.
	go func() {
		sklog.Infof("Listening for PubSub messages.")
		for {
			if err := subscription.Receive(ctx, func(ctx context.Context, msg *pubsub.Message) {
				evt := gcsPubSubEvent{}
				if err := json.Unmarshal(msg.Data, &evt); err != nil {
					// This should never happen. But if it does, then GCS is sending spurious messages, or
					// something else is publishing on the topic.
					msg.Ack() // No point in retrying a spurious message.
					// TODO(lovisolo): Add a metrics counter.
					sklog.Errorf("Received malformed PubSub message. JSON Unmarshal error: %s\n", err)
					return
				}

				sklog.Infof("Received PubSub message: [bucket: %s, name: %s].\n", evt.Bucket, evt.Name)

				// We should only receive events for files in our GCS bucket.
				if evt.Bucket != gcsBucket {
					msg.Ack() // No point in retrying a spurious message.
					// TODO(lovisolo): Add a metrics counter.
					sklog.Errorf("Received a PubSub message from an unknown GCS bucket %q, but %q was expected. Potential configuration error.", evt.Bucket, gcsBucket)
					return
				}

				// Process message.
				if err := srv.handleFileUploadNotification(ctx, evt.Name); err != nil {
					// TODO(lovisolo): Add a metrics counter.
					sklog.Warningf("Failed to process PubSub message: [bucket: %s, name: %s]. Error: %s.\n", evt.Bucket, evt.Name, err)

					// We Ack messages we failed to process to prevent them from being continuously retried.
					// Some of these errors might be retriable, such as transient network errors while
					// downloading from GCS, but I don't anticipate this to happen often. As is, such an error
					// would prevent the replica from picking up the latest Bloaty output, but this would
					// resolve itself as soon as the next Skia commit lands.
					//
					// If our metrics indicate that we're failing to process lots of messages, an alternative
					// is to Nack failed messages so as to retry them, and set up a dead-letter topic
					// (https://cloud.google.com/pubsub/docs/handling-failures) with a small
					// MaxDeliveryAttempts value in order to limit the number of retries.
					msg.Ack()
				} else {
					// TODO(lovisolo): Add a metrics counter.
					sklog.Infof("Done processing PubSub message: [bucket: %s, name: %s].\n", evt.Bucket, evt.Name)
					msg.Ack()
				}
			}); err != nil {
				// Receive returns a non-retryable error, so we log with Fatal to exit the program.
				sklog.Fatal(err)
			}
		}
	}()

	srv.loadTemplates()

	return srv, nil
}

// preloadBloatyFiles preloads the latest Bloaty outputs for each supported build artifact.
func (s *server) preloadBloatyFiles(ctx context.Context) error {
	// We'll filter out anything that isn't under a YYYY/MM/DD directory and doesn't end in ".tsv".
	// This excludes debug files that we occasionally upload to GCS.
	bloatyOutputFilePattern := regexp.MustCompile(`^[0-9]{4}/[0-9]{2}/[0-9]{2}/.*\.tsv$`)

	n := now.Now(ctx).UTC()
	dirs := fileutil.GetHourlyDirs("", n.Add(-daysToPreload*24*time.Hour), n)
	if *baseapp.Local {
		dirs = fileutil.GetHourlyDirs("", n.Add(-8*time.Hour), n)
	}
	sklog.Debugf("Preloading data, starting in folder %s", dirs[0])
	for _, dir := range dirs {
		err := s.gcsClient.AllFilesInDirectory(ctx, dir, func(item *storage.ObjectAttrs) error {
			if !bloatyOutputFilePattern.MatchString(item.Name) {
				return nil
			}
			if err := s.store.Index(ctx, item.Name); err != nil {
				// If this happens often (e.g. because we're hitting a GCS QPS limit) we can do a combination
				// of limiting our QPS rate and only fetching the most recent files.
				//
				// As is, this is probably fine. At worst, the app will crash and Kubernetes will retry
				// creating the pod, entering a crash loop if we're still over the QPS quota. Exponential
				// backoff would be a potential mitigation.
				sklog.Fatalf("Error while preloading %s: %s\n", item.Name, err)
			}
			return nil
		})
		if err != nil {
			return skerr.Wrap(err)
		}
	}

	return nil
}

// handleFileUploadNotification is called when a new file is uploaded to the GCS bucket.
func (s *server) handleFileUploadNotification(ctx context.Context, path string) error {
	sklog.Infof("Received file upload PubSub message: %s", path)
	if strings.HasSuffix(path, ".json") || strings.HasSuffix(path, ".diff.txt") {
		sklog.Infof("Ignoring %s because we index .json and .diff.txt files when we see a corresponding .tsv file", path)
		return nil
	}
	if err := s.store.Index(ctx, path); err != nil {
		return skerr.Wrap(err)
	}
	return nil
}

// loadTemplates loads the HTML templates to serve to the UI.
func (s *server) loadTemplates() {
	s.templates = template.Must(template.New("").Delims("{%", "%}").ParseGlob(
		filepath.Join(*baseapp.ResourcesDir, "*.html"),
	))
}

// sendJSONResponse sends a JSON representation of any data structure as an HTTP response. If the
// conversion to JSON has an error, the error is logged.
func sendJSONResponse(data interface{}, w http.ResponseWriter) {
	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(data); err != nil {
		sklog.Errorf("Failed to write response: %s", err)
	}
}

// sendHTMLResponse renders the given template, passing it the current context's CSP nonce. If
// template rendering fails, it logs an error.
func (s *server) sendHTMLResponse(templateName string, w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	if err := s.templates.ExecuteTemplate(w, templateName, map[string]string{
		"Nonce": secure.CSPNonce(r.Context()),
	}); err != nil {
		sklog.Errorf("Failed to expand template: %s", err)
	}
}

func (s *server) indexPageHandler(w http.ResponseWriter, r *http.Request) {
	s.sendHTMLResponse("index.html", w, r)
}

func (s *server) binaryPageHandler(w http.ResponseWriter, r *http.Request) {
	s.sendHTMLResponse("binary.html", w, r)
}

func (s *server) binaryDiffPageHandler(w http.ResponseWriter, r *http.Request) {
	s.sendHTMLResponse("binary_diff.html", w, r)
}

func (s *server) binaryRPCHandler(w http.ResponseWriter, r *http.Request) {
	req := rpc.BinaryRPCRequest{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		httputils.ReportError(w, err, "Failed to parse request", http.StatusBadRequest)
		return
	}

	binary, ok := s.store.GetBinary(req.CommitOrPatchset, req.BinaryName, req.CompileTaskName)
	if !ok {
		httputils.ReportError(w, nil, "Binary not found in Store", http.StatusNotFound)
		return
	}

	bytes, err := s.store.GetBloatyOutputFileContents(r.Context(), binary)
	if err != nil {
		httputils.ReportError(w, err, "Failed to retrieve Bloaty output file", http.StatusInternalServerError)
		return
	}

	outputItems, err := bloaty.ParseTSVOutput(string(bytes))
	if err != nil {
		httputils.ReportError(w, err, "Failed to parse Bloaty output file.", http.StatusInternalServerError)
		return
	}

	res := rpc.BinaryRPCResponse{
		Metadata: binary.Metadata,
		Rows:     bloaty.GenTreeMapDataTableRows(outputItems, maxChildrenPerParent),
	}
	sendJSONResponse(res, w)
}

func (s *server) binarySizeDiffRPCHandler(w http.ResponseWriter, r *http.Request) {
	req := rpc.BinarySizeDiffRPCRequest{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		httputils.ReportError(w, err, "Failed to parse request", http.StatusBadRequest)
		return
	}

	binary, ok := s.store.GetBinary(req.CommitOrPatchset, req.BinaryName, req.CompileTaskName)
	if !ok {
		httputils.ReportError(w, nil, "Binary not found in Store", http.StatusNotFound)
		return
	}

	bytes, err := s.store.GetBloatySizeDiffOutputFileContents(r.Context(), binary)
	if err != nil {
		httputils.ReportError(w, err, "Failed to retrieve Bloaty output file", http.StatusInternalServerError)
		return
	}

	res := rpc.BinarySizeDiffRPCResponse{
		Metadata: binary.Metadata,
		RawDiff:  string(bytes),
	}
	sendJSONResponse(res, w)
}

func (s *server) mostRecentBinariesRPCHandler(w http.ResponseWriter, r *http.Request) {
	binaries := s.store.GetMostRecentBinaries(numMostRecentBinaries)
	res := rpc.MostRecentBinariesRPCResponse{
		Binaries: binaries,
	}
	sendJSONResponse(res, w)
}

// See baseapp.App.
func (s *server) AddHandlers(r chi.Router) {
	r.Get("/", s.indexPageHandler)
	r.Get("/binary", s.binaryPageHandler)
	r.Get("/binary_diff", s.binaryDiffPageHandler)
	r.Post("/rpc/binary/v1", s.binaryRPCHandler)
	r.Post("/rpc/binary_size_diff/v1", s.binarySizeDiffRPCHandler)
	r.Get("/rpc/most_recent_binaries/v1", s.mostRecentBinariesRPCHandler)
}

// See baseapp.App.
func (s *server) AddMiddleware() []func(http.Handler) http.Handler {
	return []func(http.Handler) http.Handler{}
}

func main() {
	baseapp.Serve(new, []string{"codesize.skia.org"})
}
