// docserver is a super simple Markdown (CommonMark) server.
//
// Every directory has an index.md and the first line of index.md is used as
// the display name for that directory. The directory name itself is used in
// the URL path. See README.md for more design details.
package main

import (
	"context"
	"flag"
	"fmt"
	"mime"
	"net/http"
	"net/url"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"
	"text/template"
	"time"

	"cloud.google.com/go/storage"
	"github.com/fiorix/go-web/autogzip"
	"github.com/gorilla/mux"
	"github.com/russross/blackfriday"
	"go.skia.org/infra/docserverk/go/docset"
	"go.skia.org/infra/docserverk/go/ssi"
	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/login"
	"go.skia.org/infra/go/sklog"
	"google.golang.org/api/option"
)

var (
	indexTemplate *template.Template

	primary *docset.DocSet
)

// flags
var (
	docRepo      = flag.String("doc_repo", "https://skia.googlesource.com/skia", "The repo to check out.")
	local        = flag.Bool("local", false, "Running locally if true. As opposed to in production.")
	port         = flag.String("port", ":8000", "HTTP service address (e.g., ':8000')")
	preview      = flag.Bool("preview", false, "Preview markdown changes to a local repo. Doesn't do pulls.")
	promPort     = flag.String("prom_port", ":20000", "Metrics service address (e.g., ':10110')")
	refresh      = flag.Duration("refresh", 5*time.Minute, "The duration between doc git repo refreshes.")
	resourcesDir = flag.String("resources_dir", "", "The directory to find templates, JS, and CSS files. If blank the current directory will be used.")
	workDir      = flag.String("work_dir", "/tmp", "The directory to check out the doc repo into.")
)

func loadTemplates() {
	indexTemplate = template.Must(template.ParseFiles(
		filepath.Join(*resourcesDir, "templates/index.html"),
	))
}

func Init() {
	tokenSrc, err := auth.NewDefaultTokenSource(*local)
	if err != nil {
		sklog.Fatalf("Unable to obtain auth token source: %s", err)
	}

	storageClient, err := storage.NewClient(context.Background(), option.WithTokenSource(tokenSrc))
	if err != nil {
		sklog.Fatalf("Unable to instantiate GCS client: %s", err)
	}
	ssi.Init(*docRepo, storageClient)

	if *resourcesDir == "" {
		_, filename, _, _ := runtime.Caller(0)
		*resourcesDir = filepath.Join(filepath.Dir(filename), "../..")
	}
	loadTemplates()

	if err = docset.Init(); err != nil {
		sklog.Fatalf("Failed to initialize docset: %s", err)
	}
	if *preview {
		primary, err = docset.NewPreviewDocSet()
	} else {
		primary, err = docset.NewDocSet(context.Background(), *workDir, *docRepo)
	}
	if err != nil {
		sklog.Fatalf("Failed to load the docset: %s", err)
	}
	if !*preview {
		go docset.StartCleaner(*workDir)
	}
}

type Content struct {
	Body string
	Nav  string
}

// mainHandler handles the GET of the main page.
//
// Handles servering all the processed Markdown documents
// and other assetts in the doc repo.
func mainHandler(w http.ResponseWriter, r *http.Request) {
	sklog.Infof("Main Handler: %q\n", r.URL.Path)

	// If the request begins with /_/ then it is an XHR request and we only need
	// to return the content and not the surrounding markup.
	bodyOnly := false
	if strings.HasPrefix(r.URL.Path, "/_/") {
		bodyOnly = true
		r.URL.Path = r.URL.Path[2:]
	}

	d := primary
	// If there is a cl={issue_number} query parameter supplied then
	// clone a new copy of the docs repo and patch that issue into it,
	// and then serve this reqeust from that patched repo.
	cl := r.FormValue("cl")

	// Images and other assets won't include the ?cl=[issueid], which means if we
	// add a new image in a CL it won't normally show up in the preview, but we
	// can extract the issue id from the Referer header if present.
	ref := r.Header.Get("Referer")
	if cl == "" && ref != "" {
		if refParsed, err := url.Parse(ref); err == nil && (refParsed.Host == r.Host || refParsed.Host == "skia.org") {
			cl = refParsed.Query().Get("cl")
		}
	}
	if cl != "" {
		issue, err := strconv.ParseInt(cl, 10, 64)
		if err != nil {
			httputils.ReportError(w, r, fmt.Errorf("Not a valid integer id for an issue."), "The CL given is not valid.")
			return
		}
		d, err = docset.NewDocSetForIssue(context.Background(), *workDir, *docRepo, issue)
		if err == docset.IssueCommittedErr {
			httputils.ReportError(w, r, err, "Failed to load the given CL, that issue is closed.")
			return
		}
		if err != nil {
			httputils.ReportError(w, r, err, "Failed to load the given CL.")
			return
		}
	}

	// When running in local mode reload all templates and rebuild the navigation
	// menu on every request, so we don't have to start and stop the server while
	// developing.
	if *local {
		d.BuildNavigation()
		loadTemplates()
	}
	if r.URL.Path == "/sitemap.txt" {
		w.Header().Set("Content-Type", "text/plain")
		if _, err := w.Write([]byte(d.SiteMap())); err != nil {
			sklog.Errorf("Failed to write sitemap.txt: %s", err)
		}
		return
	}

	filename, raw, err := d.RawFilename(r.URL.Path)
	if err != nil {
		sklog.Infof("Request for unknown path: %s", r.URL.Path)
		http.NotFound(w, r)
		return
	}

	// Set the content type.
	mimetype := "text/html"
	if raw {
		mimetype = mime.TypeByExtension(filepath.Ext(filename))
	}
	w.Header().Set("Content-Type", mimetype)

	// Write the response.
	b, err := d.Body(filename)
	if err != nil {
		httputils.ReportError(w, r, err, "Failed to load file")
		return
	}
	if raw {
		if _, err := w.Write(b); err != nil {
			sklog.Errorf("Failed to write output: %s", err)
			return
		}
	} else {
		body := blackfriday.MarkdownCommon(b)

		// Resolve the serve side includes if there are any.
		if body, err = ssi.ProcessSSI(body); err != nil {
			httputils.ReportError(w, r, err, "Failed to load file")
			return
		}

		if bodyOnly {
			if _, err := w.Write(body); err != nil {
				sklog.Errorf("Failed to write output: %s", err)
				return
			}
		} else {
			content := &Content{
				Body: string(body),
				Nav:  d.Navigation(),
			}
			if err := indexTemplate.Execute(w, content); err != nil {
				sklog.Errorln("Failed to expand template:", err)
			}
		}
	}
}

func makeResourceHandler() func(http.ResponseWriter, *http.Request) {
	fileServer := http.FileServer(http.Dir(*resourcesDir))
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add("Cache-Control", "max-age=300")
		fileServer.ServeHTTP(w, r)
	}
}

func main() {
	common.InitWithMust(
		"docserver",
		common.PrometheusOpt(promPort),
		common.MetricsLoggingOpt(),
	)

	if !*local {
		login.SimpleInitMust(*port, *local)
	}

	Init()

	router := mux.NewRouter()
	// Resources are served directly.
	router.PathPrefix("/res/").HandlerFunc(makeResourceHandler())

	if !*local {
		router.HandleFunc("/logout/", login.LogoutHandler)
		router.HandleFunc("/loginstatus/", login.StatusHandler)
		router.HandleFunc("/oauth2callback/", login.OAuth2CallbackHandler)
	}

	router.PathPrefix("/").HandlerFunc(autogzip.HandleFunc(mainHandler))

	var h http.Handler = router
	if !*local {
		h = httputils.HealthzAndHTTPS(h)
	}
	http.Handle("/", h)

	sklog.Infoln("Ready to serve.")
	sklog.Fatal(http.ListenAndServe(*port, nil))
}
