package main

// The webserver for demos.skia.org. It serves a main page and a set of js+html+css demos.

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"sync"
	"time"

	"github.com/go-chi/chi/v5"

	"go.skia.org/infra/demos/go/frontend"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
)

const (
	repoPollInterval = 3 * time.Minute
)

func main() {
	var (
		port         = flag.String("port", ":8000", "HTTP service address (e.g., ':8000')")
		resourcesDir = flag.String("resources_dir", "./dist", "The directory to find templates, JS, and CSS files. If blank ./dist will be used.")
		repoURL      = flag.String("repo_url", "https://skia.googlesource.com/infra-internal", "The repo from where to fetch the demos. Defaults to https://skia.googlesource.com/infra-internal")
		demosDir     = flag.String("demos_dir", "demos/internal", "The top level directory in the repo that holds the demos.")
		branch       = flag.String("repo_default_branch", git.MainBranch, "The branch of the repo to sync (ie. master or main).")

		unsyncedRepoPath = flag.String("unsynced_repo_path", "unset", "If set, will use an already existing Skia checkout and not sync it.")
	)
	common.InitWithMust(
		"demos",
	)

	ctx := context.Background()
	// Create a threadsafe checkout to serve from.
	checkoutDir, err := os.MkdirTemp("", "demos_repo")
	if err != nil {
		sklog.Fatalf("Unable to create temporary directory for demos checkout: %s", err)
	}
	var demos *syncedDemos
	if *unsyncedRepoPath != "unset" {
		if empty, err := util.IsDirEmpty(*unsyncedRepoPath); err != nil || empty {
			sklog.Fatalf("If unsynced_repo_path is specified, it cannot be empty. Do you have the environment variable SKIA_ROOT set?")
		}
		demos = newUnsyncedDemos(*unsyncedRepoPath, *demosDir)
	} else {
		demos = newSyncedDemos(ctx, *repoURL, *branch, checkoutDir, *demosDir)
	}

	r := chi.NewRouter()
	r.HandleFunc("/demo/*", demos.demoHandler())
	r.Handle("/dist/*", http.StripPrefix("/dist/", http.FileServer(http.Dir(*resourcesDir))))
	r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, filepath.Join(*resourcesDir, "main.html"))
	})

	h := httputils.LoggingGzipRequestResponse(r)
	h = httputils.HealthzAndHTTPS(h)
	http.Handle("/", h)
	sklog.Info("Ready to serve on http://localhost" + *port)
	sklog.Fatal(http.ListenAndServe(*port, nil))
}

type syncedDemos struct {
	sync.RWMutex
	repo    git.Checkout
	repoURL string
	branch  string
	// Absolute path where demos are located.
	demoPath string
}

// newSyncedDemos creates a *syncedDemos that maintains a thread compatible, updating repo.
//
// It periodically updates the repo under a lock, and writes a metadata file to demoPath listing
// the available subdirectories and other repo information. The repo files can be safely served
// by exposing DemoHandler().
func newSyncedDemos(ctx context.Context, repoURL, branch, checkoutDir, demoPath string) *syncedDemos {
	sklog.Infof("Creating new syncedDemos for %s at %s", repoURL, checkoutDir)
	s := &syncedDemos{
		branch:  branch,
		repoURL: repoURL,
	}
	var err error
	s.repo, err = git.NewCheckout(ctx, repoURL, checkoutDir)
	if err != nil {
		sklog.Fatal(err)
	}
	s.demoPath = filepath.Join(s.repo.Dir(), demoPath)
	sklog.Infof("Serving demos out of '%s'", s.demoPath)

	go util.RepeatCtx(ctx, repoPollInterval, s.Sync)
	return s
}

// newUnsyncedDemos creates a *syncedDemos pointing to an existing Skia checkout.
// It does not periodically update anything; this is meant to expedite local development.
func newUnsyncedDemos(checkoutDir, demoPath string) *syncedDemos {
	return &syncedDemos{
		demoPath: filepath.Join(checkoutDir, demoPath),
	}
}

// writeMetadata writes a json file containing the list of subdirectories in s.demoPath as well as
// the hash and URL of the current s.repo revision.
//
// This is used to generate a list of demo links on the skia-demos main page.
func (s *syncedDemos) writeMetadata(rev string) error {
	file, err := os.Open(s.demoPath)
	if err != nil {
		return skerr.Wrapf(err, "Failed to Open '%s'.", s.demoPath)
	}
	defer file.Close()
	metadata := frontend.Metadata{
		Rev: frontend.Revision{
			Hash: rev,
			URL:  fmt.Sprintf("%s/+/%s", s.repoURL, rev),
		},
	}
	metadata.DemoList, err = file.Readdirnames(0)
	if err != nil {
		return skerr.Wrapf(err, "Failed to Readdirnames of '%s'.", file.Name())
	}
	sklog.Infof("Available demos: %v", metadata.DemoList)

	obj, err := json.MarshalIndent(metadata, "", "  ")
	if err != nil {
		return skerr.Wrap(err)
	}
	metadataPath := filepath.Join(s.demoPath, "metadata.json")
	err = os.WriteFile(metadataPath, obj, 0644)
	if err != nil {
		return skerr.Wrapf(err, "Unable to write json to '%s'.", metadataPath)
	}
	return nil
}

// Sync performs a repo Update under s.Lock().
//
// If the HEAD revision changes it rewrites the metadata.json file with updated information.
func (s *syncedDemos) Sync(ctx context.Context) {
	sklog.Info("Syncing and rewriting metadata file.")
	s.Lock()
	defer s.Unlock()

	if err := s.repo.UpdateBranch(ctx, s.branch); err != nil {
		sklog.Errorf("Failed to update repo: %s", err)
	}

	hash, err := s.repo.FullHash(ctx, "HEAD")
	if err != nil {
		sklog.Fatal(err)
	}

	sklog.Infof("Checkout at %s.", hash)

	if err = s.writeMetadata(hash); err != nil {
		sklog.Fatalf("Unable to write metadata: %s", err)
	}
}

// demoHandler returns a fileserver handler for dir that won't serve while the underlying repo
// is being updated.
func (s *syncedDemos) demoHandler() func(http.ResponseWriter, *http.Request) {
	h := http.StripPrefix("/demo", http.FileServer(http.Dir(s.demoPath)))
	return func(w http.ResponseWriter, r *http.Request) {
		s.RLock()
		defer s.RUnlock()
		h.ServeHTTP(w, r)
	}
}
