// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package debug

import (
	"archive/zip"
	"bytes"
	"context"
	"errors"
	"fmt"
	"html/template"
	"io"
	stdlog "log"
	"net"
	"net/http"
	"net/http/pprof"
	"os"
	"path"
	"path/filepath"
	"runtime"
	rpprof "runtime/pprof"
	"strconv"
	"strings"
	"sync"
	"time"

	"golang.org/x/tools/gopls/internal/lsp/cache"
	"golang.org/x/tools/gopls/internal/lsp/debug/log"
	"golang.org/x/tools/gopls/internal/lsp/protocol"
	"golang.org/x/tools/internal/bug"
	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/event/core"
	"golang.org/x/tools/internal/event/export"
	"golang.org/x/tools/internal/event/export/metric"
	"golang.org/x/tools/internal/event/export/ocagent"
	"golang.org/x/tools/internal/event/export/prometheus"
	"golang.org/x/tools/internal/event/keys"
	"golang.org/x/tools/internal/event/label"
	"golang.org/x/tools/internal/event/tag"
)

type contextKeyType int

const (
	instanceKey contextKeyType = iota
	traceKey
)

// An Instance holds all debug information associated with a gopls instance.
type Instance struct {
	Logfile       string
	StartTime     time.Time
	ServerAddress string
	Workdir       string
	OCAgentConfig string

	LogWriter io.Writer

	exporter event.Exporter

	ocagent    *ocagent.Exporter
	prometheus *prometheus.Exporter
	rpcs       *Rpcs
	traces     *traces
	State      *State

	serveMu              sync.Mutex
	debugAddress         string
	listenedDebugAddress string
}

// State holds debugging information related to the server state.
type State struct {
	mu      sync.Mutex
	clients []*Client
	servers []*Server
}

func (st *State) Bugs() []bug.Bug {
	return bug.List()
}

// Caches returns the set of Cache objects currently being served.
func (st *State) Caches() []*cache.Cache {
	var caches []*cache.Cache
	seen := make(map[string]struct{})
	for _, client := range st.Clients() {
		cache := client.Session.Cache()
		if _, found := seen[cache.ID()]; found {
			continue
		}
		seen[cache.ID()] = struct{}{}
		caches = append(caches, cache)
	}
	return caches
}

// Cache returns the Cache that matches the supplied id.
func (st *State) Cache(id string) *cache.Cache {
	for _, c := range st.Caches() {
		if c.ID() == id {
			return c
		}
	}
	return nil
}

// Sessions returns the set of Session objects currently being served.
func (st *State) Sessions() []*cache.Session {
	var sessions []*cache.Session
	for _, client := range st.Clients() {
		sessions = append(sessions, client.Session)
	}
	return sessions
}

// Session returns the Session that matches the supplied id.
func (st *State) Session(id string) *cache.Session {
	for _, s := range st.Sessions() {
		if s.ID() == id {
			return s
		}
	}
	return nil
}

// Views returns the set of View objects currently being served.
func (st *State) Views() []*cache.View {
	var views []*cache.View
	for _, s := range st.Sessions() {
		for _, v := range s.Views() {
			if cv, ok := v.(*cache.View); ok {
				views = append(views, cv)
			}
		}
	}
	return views
}

// View returns the View that matches the supplied id.
func (st *State) View(id string) *cache.View {
	for _, v := range st.Views() {
		if v.ID() == id {
			return v
		}
	}
	return nil
}

// Clients returns the set of Clients currently being served.
func (st *State) Clients() []*Client {
	st.mu.Lock()
	defer st.mu.Unlock()
	clients := make([]*Client, len(st.clients))
	copy(clients, st.clients)
	return clients
}

// Client returns the Client matching the supplied id.
func (st *State) Client(id string) *Client {
	for _, c := range st.Clients() {
		if c.Session.ID() == id {
			return c
		}
	}
	return nil
}

// Servers returns the set of Servers the instance is currently connected to.
func (st *State) Servers() []*Server {
	st.mu.Lock()
	defer st.mu.Unlock()
	servers := make([]*Server, len(st.servers))
	copy(servers, st.servers)
	return servers
}

// A Client is an incoming connection from a remote client.
type Client struct {
	Session      *cache.Session
	DebugAddress string
	Logfile      string
	GoplsPath    string
	ServerID     string
	Service      protocol.Server
}

// A Server is an outgoing connection to a remote LSP server.
type Server struct {
	ID           string
	DebugAddress string
	Logfile      string
	GoplsPath    string
	ClientID     string
}

// AddClient adds a client to the set being served.
func (st *State) addClient(session *cache.Session) {
	st.mu.Lock()
	defer st.mu.Unlock()
	st.clients = append(st.clients, &Client{Session: session})
}

// DropClient removes a client from the set being served.
func (st *State) dropClient(session *cache.Session) {
	st.mu.Lock()
	defer st.mu.Unlock()
	for i, c := range st.clients {
		if c.Session == session {
			copy(st.clients[i:], st.clients[i+1:])
			st.clients[len(st.clients)-1] = nil
			st.clients = st.clients[:len(st.clients)-1]
			return
		}
	}
}

// AddServer adds a server to the set being queried. In practice, there should
// be at most one remote server.
func (st *State) updateServer(server *Server) {
	st.mu.Lock()
	defer st.mu.Unlock()
	for i, existing := range st.servers {
		if existing.ID == server.ID {
			// Replace, rather than mutate, to avoid a race.
			newServers := make([]*Server, len(st.servers))
			copy(newServers, st.servers[:i])
			newServers[i] = server
			copy(newServers[i+1:], st.servers[i+1:])
			st.servers = newServers
			return
		}
	}
	st.servers = append(st.servers, server)
}

// DropServer drops a server from the set being queried.
func (st *State) dropServer(id string) {
	st.mu.Lock()
	defer st.mu.Unlock()
	for i, s := range st.servers {
		if s.ID == id {
			copy(st.servers[i:], st.servers[i+1:])
			st.servers[len(st.servers)-1] = nil
			st.servers = st.servers[:len(st.servers)-1]
			return
		}
	}
}

// an http.ResponseWriter that filters writes
type filterResponse struct {
	w    http.ResponseWriter
	edit func([]byte) []byte
}

func (c filterResponse) Header() http.Header {
	return c.w.Header()
}

func (c filterResponse) Write(buf []byte) (int, error) {
	ans := c.edit(buf)
	return c.w.Write(ans)
}

func (c filterResponse) WriteHeader(n int) {
	c.w.WriteHeader(n)
}

// replace annoying nuls by spaces
func cmdline(w http.ResponseWriter, r *http.Request) {
	fake := filterResponse{
		w: w,
		edit: func(buf []byte) []byte {
			return bytes.ReplaceAll(buf, []byte{0}, []byte{' '})
		},
	}
	pprof.Cmdline(fake, r)
}

func (i *Instance) getCache(r *http.Request) interface{} {
	return i.State.Cache(path.Base(r.URL.Path))
}

func (i *Instance) getSession(r *http.Request) interface{} {
	return i.State.Session(path.Base(r.URL.Path))
}

func (i *Instance) getClient(r *http.Request) interface{} {
	return i.State.Client(path.Base(r.URL.Path))
}

func (i *Instance) getServer(r *http.Request) interface{} {
	i.State.mu.Lock()
	defer i.State.mu.Unlock()
	id := path.Base(r.URL.Path)
	for _, s := range i.State.servers {
		if s.ID == id {
			return s
		}
	}
	return nil
}

func (i *Instance) getView(r *http.Request) interface{} {
	return i.State.View(path.Base(r.URL.Path))
}

func (i *Instance) getFile(r *http.Request) interface{} {
	identifier := path.Base(r.URL.Path)
	sid := path.Base(path.Dir(r.URL.Path))
	s := i.State.Session(sid)
	if s == nil {
		return nil
	}
	for _, o := range s.Overlays() {
		// TODO(adonovan): understand and document this comparison.
		if o.FileIdentity().Hash.String() == identifier {
			return o
		}
	}
	return nil
}

func (i *Instance) getInfo(r *http.Request) interface{} {
	buf := &bytes.Buffer{}
	i.PrintServerInfo(r.Context(), buf)
	return template.HTML(buf.String())
}

func (i *Instance) AddService(s protocol.Server, session *cache.Session) {
	for _, c := range i.State.clients {
		if c.Session == session {
			c.Service = s
			return
		}
	}
	stdlog.Printf("unable to find a Client to add the protocol.Server to")
}

func getMemory(_ *http.Request) interface{} {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	return m
}

func init() {
	event.SetExporter(makeGlobalExporter(os.Stderr))
}

func GetInstance(ctx context.Context) *Instance {
	if ctx == nil {
		return nil
	}
	v := ctx.Value(instanceKey)
	if v == nil {
		return nil
	}
	return v.(*Instance)
}

// WithInstance creates debug instance ready for use using the supplied
// configuration and stores it in the returned context.
func WithInstance(ctx context.Context, workdir, agent string) context.Context {
	i := &Instance{
		StartTime:     time.Now(),
		Workdir:       workdir,
		OCAgentConfig: agent,
	}
	i.LogWriter = os.Stderr
	ocConfig := ocagent.Discover()
	//TODO: we should not need to adjust the discovered configuration
	ocConfig.Address = i.OCAgentConfig
	i.ocagent = ocagent.Connect(ocConfig)
	i.prometheus = prometheus.New()
	i.rpcs = &Rpcs{}
	i.traces = &traces{}
	i.State = &State{}
	i.exporter = makeInstanceExporter(i)
	return context.WithValue(ctx, instanceKey, i)
}

// SetLogFile sets the logfile for use with this instance.
func (i *Instance) SetLogFile(logfile string, isDaemon bool) (func(), error) {
	// TODO: probably a better solution for deferring closure to the caller would
	// be for the debug instance to itself be closed, but this fixes the
	// immediate bug of logs not being captured.
	closeLog := func() {}
	if logfile != "" {
		if logfile == "auto" {
			if isDaemon {
				logfile = filepath.Join(os.TempDir(), fmt.Sprintf("gopls-daemon-%d.log", os.Getpid()))
			} else {
				logfile = filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.log", os.Getpid()))
			}
		}
		f, err := os.Create(logfile)
		if err != nil {
			return nil, fmt.Errorf("unable to create log file: %w", err)
		}
		closeLog = func() {
			defer f.Close()
		}
		stdlog.SetOutput(io.MultiWriter(os.Stderr, f))
		i.LogWriter = f
	}
	i.Logfile = logfile
	return closeLog, nil
}

// Serve starts and runs a debug server in the background on the given addr.
// It also logs the port the server starts on, to allow for :0 auto assigned
// ports.
func (i *Instance) Serve(ctx context.Context, addr string) (string, error) {
	stdlog.SetFlags(stdlog.Lshortfile)
	if addr == "" {
		return "", nil
	}
	i.serveMu.Lock()
	defer i.serveMu.Unlock()

	if i.listenedDebugAddress != "" {
		// Already serving. Return the bound address.
		return i.listenedDebugAddress, nil
	}

	i.debugAddress = addr
	listener, err := net.Listen("tcp", i.debugAddress)
	if err != nil {
		return "", err
	}
	i.listenedDebugAddress = listener.Addr().String()

	port := listener.Addr().(*net.TCPAddr).Port
	if strings.HasSuffix(i.debugAddress, ":0") {
		stdlog.Printf("debug server listening at http://localhost:%d", port)
	}
	event.Log(ctx, "Debug serving", tag.Port.Of(port))
	go func() {
		mux := http.NewServeMux()
		mux.HandleFunc("/", render(MainTmpl, func(*http.Request) interface{} { return i }))
		mux.HandleFunc("/debug/", render(DebugTmpl, nil))
		mux.HandleFunc("/debug/pprof/", pprof.Index)
		mux.HandleFunc("/debug/pprof/cmdline", cmdline)
		mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
		mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
		mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
		if i.prometheus != nil {
			mux.HandleFunc("/metrics/", i.prometheus.Serve)
		}
		if i.rpcs != nil {
			mux.HandleFunc("/rpc/", render(RPCTmpl, i.rpcs.getData))
		}
		if i.traces != nil {
			mux.HandleFunc("/trace/", render(TraceTmpl, i.traces.getData))
		}
		mux.HandleFunc("/cache/", render(CacheTmpl, i.getCache))
		mux.HandleFunc("/session/", render(SessionTmpl, i.getSession))
		mux.HandleFunc("/view/", render(ViewTmpl, i.getView))
		mux.HandleFunc("/client/", render(ClientTmpl, i.getClient))
		mux.HandleFunc("/server/", render(ServerTmpl, i.getServer))
		mux.HandleFunc("/file/", render(FileTmpl, i.getFile))
		mux.HandleFunc("/info", render(InfoTmpl, i.getInfo))
		mux.HandleFunc("/memory", render(MemoryTmpl, getMemory))

		mux.HandleFunc("/_makeabug", func(w http.ResponseWriter, r *http.Request) {
			bug.Report("bug here", nil)
			http.Error(w, "made a bug", http.StatusOK)
		})

		if err := http.Serve(listener, mux); err != nil {
			event.Error(ctx, "Debug server failed", err)
			return
		}
		event.Log(ctx, "Debug server finished")
	}()
	return i.listenedDebugAddress, nil
}

func (i *Instance) DebugAddress() string {
	i.serveMu.Lock()
	defer i.serveMu.Unlock()
	return i.debugAddress
}

func (i *Instance) ListenedDebugAddress() string {
	i.serveMu.Lock()
	defer i.serveMu.Unlock()
	return i.listenedDebugAddress
}

// MonitorMemory starts recording memory statistics each second.
func (i *Instance) MonitorMemory(ctx context.Context) {
	tick := time.NewTicker(time.Second)
	nextThresholdGiB := uint64(1)
	go func() {
		for {
			<-tick.C
			var mem runtime.MemStats
			runtime.ReadMemStats(&mem)
			if mem.HeapAlloc < nextThresholdGiB*1<<30 {
				continue
			}
			if err := i.writeMemoryDebug(nextThresholdGiB, true); err != nil {
				event.Error(ctx, "writing memory debug info", err)
			}
			if err := i.writeMemoryDebug(nextThresholdGiB, false); err != nil {
				event.Error(ctx, "writing memory debug info", err)
			}
			event.Log(ctx, fmt.Sprintf("Wrote memory usage debug info to %v", os.TempDir()))
			nextThresholdGiB++
		}
	}()
}

func (i *Instance) writeMemoryDebug(threshold uint64, withNames bool) error {
	suffix := "withnames"
	if !withNames {
		suffix = "nonames"
	}

	filename := fmt.Sprintf("gopls.%d-%dGiB-%s.zip", os.Getpid(), threshold, suffix)
	zipf, err := os.OpenFile(filepath.Join(os.TempDir(), filename), os.O_CREATE|os.O_RDWR, 0644)
	if err != nil {
		return err
	}
	zipw := zip.NewWriter(zipf)

	f, err := zipw.Create("heap.pb.gz")
	if err != nil {
		return err
	}
	if err := rpprof.Lookup("heap").WriteTo(f, 0); err != nil {
		return err
	}

	f, err = zipw.Create("goroutines.txt")
	if err != nil {
		return err
	}
	if err := rpprof.Lookup("goroutine").WriteTo(f, 1); err != nil {
		return err
	}

	for _, cache := range i.State.Caches() {
		cf, err := zipw.Create(fmt.Sprintf("cache-%v.html", cache.ID()))
		if err != nil {
			return err
		}
		if _, err := cf.Write([]byte(cache.PackageStats(withNames))); err != nil {
			return err
		}
	}

	if err := zipw.Close(); err != nil {
		return err
	}
	return zipf.Close()
}

func makeGlobalExporter(stderr io.Writer) event.Exporter {
	p := export.Printer{}
	var pMu sync.Mutex
	return func(ctx context.Context, ev core.Event, lm label.Map) context.Context {
		i := GetInstance(ctx)

		if event.IsLog(ev) {
			// Don't log context cancellation errors.
			if err := keys.Err.Get(ev); errors.Is(err, context.Canceled) {
				return ctx
			}
			// Make sure any log messages without an instance go to stderr.
			if i == nil {
				pMu.Lock()
				p.WriteEvent(stderr, ev, lm)
				pMu.Unlock()
			}
			level := log.LabeledLevel(lm)
			// Exclude trace logs from LSP logs.
			if level < log.Trace {
				ctx = protocol.LogEvent(ctx, ev, lm, messageType(level))
			}
		}
		if i == nil {
			return ctx
		}
		return i.exporter(ctx, ev, lm)
	}
}

func messageType(l log.Level) protocol.MessageType {
	switch l {
	case log.Error:
		return protocol.Error
	case log.Warning:
		return protocol.Warning
	case log.Debug:
		return protocol.Log
	}
	return protocol.Info
}

func makeInstanceExporter(i *Instance) event.Exporter {
	exporter := func(ctx context.Context, ev core.Event, lm label.Map) context.Context {
		if i.ocagent != nil {
			ctx = i.ocagent.ProcessEvent(ctx, ev, lm)
		}
		if i.prometheus != nil {
			ctx = i.prometheus.ProcessEvent(ctx, ev, lm)
		}
		if i.rpcs != nil {
			ctx = i.rpcs.ProcessEvent(ctx, ev, lm)
		}
		if i.traces != nil {
			ctx = i.traces.ProcessEvent(ctx, ev, lm)
		}
		if event.IsLog(ev) {
			if s := cache.KeyCreateSession.Get(ev); s != nil {
				i.State.addClient(s)
			}
			if sid := tag.NewServer.Get(ev); sid != "" {
				i.State.updateServer(&Server{
					ID:           sid,
					Logfile:      tag.Logfile.Get(ev),
					DebugAddress: tag.DebugAddress.Get(ev),
					GoplsPath:    tag.GoplsPath.Get(ev),
					ClientID:     tag.ClientID.Get(ev),
				})
			}
			if s := cache.KeyShutdownSession.Get(ev); s != nil {
				i.State.dropClient(s)
			}
			if sid := tag.EndServer.Get(ev); sid != "" {
				i.State.dropServer(sid)
			}
			if s := cache.KeyUpdateSession.Get(ev); s != nil {
				if c := i.State.Client(s.ID()); c != nil {
					c.DebugAddress = tag.DebugAddress.Get(ev)
					c.Logfile = tag.Logfile.Get(ev)
					c.ServerID = tag.ServerID.Get(ev)
					c.GoplsPath = tag.GoplsPath.Get(ev)
				}
			}
		}
		return ctx
	}
	// StdTrace must be above export.Spans below (by convention, export
	// middleware applies its wrapped exporter last).
	exporter = StdTrace(exporter)
	metrics := metric.Config{}
	registerMetrics(&metrics)
	exporter = metrics.Exporter(exporter)
	exporter = export.Spans(exporter)
	exporter = export.Labels(exporter)
	return exporter
}

type dataFunc func(*http.Request) interface{}

func render(tmpl *template.Template, fun dataFunc) func(http.ResponseWriter, *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		var data interface{}
		if fun != nil {
			data = fun(r)
		}
		if err := tmpl.Execute(w, data); err != nil {
			event.Error(context.Background(), "", err)
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	}
}

func commas(s string) string {
	for i := len(s); i > 3; {
		i -= 3
		s = s[:i] + "," + s[i:]
	}
	return s
}

func fuint64(v uint64) string {
	return commas(strconv.FormatUint(v, 10))
}

func fuint32(v uint32) string {
	return commas(strconv.FormatUint(uint64(v), 10))
}

func fcontent(v []byte) string {
	return string(v)
}

var BaseTemplate = template.Must(template.New("").Parse(`
<html>
<head>
<title>{{template "title" .}}</title>
<style>
.profile-name{
	display:inline-block;
	width:6rem;
}
td.value {
  text-align: right;
}
ul.events {
	list-style-type: none;
}

</style>
{{block "head" .}}{{end}}
</head>
<body>
<a href="/">Main</a>
<a href="/info">Info</a>
<a href="/memory">Memory</a>
<a href="/metrics">Metrics</a>
<a href="/rpc">RPC</a>
<a href="/trace">Trace</a>
<hr>
<h1>{{template "title" .}}</h1>
{{block "body" .}}
Unknown page
{{end}}
</body>
</html>

{{define "cachelink"}}<a href="/cache/{{.}}">Cache {{.}}</a>{{end}}
{{define "clientlink"}}<a href="/client/{{.}}">Client {{.}}</a>{{end}}
{{define "serverlink"}}<a href="/server/{{.}}">Server {{.}}</a>{{end}}
{{define "sessionlink"}}<a href="/session/{{.}}">Session {{.}}</a>{{end}}
{{define "viewlink"}}<a href="/view/{{.}}">View {{.}}</a>{{end}}
{{define "filelink"}}<a href="/file/{{.Session}}/{{.FileIdentity.Hash}}">{{.FileIdentity.URI}}</a>{{end}}
`)).Funcs(template.FuncMap{
	"fuint64":  fuint64,
	"fuint32":  fuint32,
	"fcontent": fcontent,
	"localAddress": func(s string) string {
		// Try to translate loopback addresses to localhost, both for cosmetics and
		// because unspecified ipv6 addresses can break links on Windows.
		//
		// TODO(rfindley): In the future, it would be better not to assume the
		// server is running on localhost, and instead construct this address using
		// the remote host.
		host, port, err := net.SplitHostPort(s)
		if err != nil {
			return s
		}
		ip := net.ParseIP(host)
		if ip == nil {
			return s
		}
		if ip.IsLoopback() || ip.IsUnspecified() {
			return "localhost:" + port
		}
		return s
	},
	"options": func(s *cache.Session) []sessionOption {
		return showOptions(s.Options())
	},
})

var MainTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}GoPls server information{{end}}
{{define "body"}}
<h2>Caches</h2>
<ul>{{range .State.Caches}}<li>{{template "cachelink" .ID}}</li>{{end}}</ul>
<h2>Sessions</h2>
<ul>{{range .State.Sessions}}<li>{{template "sessionlink" .ID}} from {{template "cachelink" .Cache.ID}}</li>{{end}}</ul>
<h2>Views</h2>
<ul>{{range .State.Views}}<li>{{.Name}} is {{template "viewlink" .ID}} from {{template "sessionlink" .Session.ID}} in {{.Folder}}</li>{{end}}</ul>
<h2>Clients</h2>
<ul>{{range .State.Clients}}<li>{{template "clientlink" .Session.ID}}</li>{{end}}</ul>
<h2>Servers</h2>
<ul>{{range .State.Servers}}<li>{{template "serverlink" .ID}}</li>{{end}}</ul>
<h2>Bug reports</h2>
<dl>{{range .State.Bugs}}<dt>{{.Key}}</dt><dd>{{.Description}}</dd>{{end}}</dl>
{{end}}
`))

var InfoTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}GoPls version information{{end}}
{{define "body"}}
{{.}}
{{end}}
`))

var MemoryTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}GoPls memory usage{{end}}
{{define "head"}}<meta http-equiv="refresh" content="5">{{end}}
{{define "body"}}
<h2>Stats</h2>
<table>
<tr><td class="label">Allocated bytes</td><td class="value">{{fuint64 .HeapAlloc}}</td></tr>
<tr><td class="label">Total allocated bytes</td><td class="value">{{fuint64 .TotalAlloc}}</td></tr>
<tr><td class="label">System bytes</td><td class="value">{{fuint64 .Sys}}</td></tr>
<tr><td class="label">Heap system bytes</td><td class="value">{{fuint64 .HeapSys}}</td></tr>
<tr><td class="label">Malloc calls</td><td class="value">{{fuint64 .Mallocs}}</td></tr>
<tr><td class="label">Frees</td><td class="value">{{fuint64 .Frees}}</td></tr>
<tr><td class="label">Idle heap bytes</td><td class="value">{{fuint64 .HeapIdle}}</td></tr>
<tr><td class="label">In use bytes</td><td class="value">{{fuint64 .HeapInuse}}</td></tr>
<tr><td class="label">Released to system bytes</td><td class="value">{{fuint64 .HeapReleased}}</td></tr>
<tr><td class="label">Heap object count</td><td class="value">{{fuint64 .HeapObjects}}</td></tr>
<tr><td class="label">Stack in use bytes</td><td class="value">{{fuint64 .StackInuse}}</td></tr>
<tr><td class="label">Stack from system bytes</td><td class="value">{{fuint64 .StackSys}}</td></tr>
<tr><td class="label">Bucket hash bytes</td><td class="value">{{fuint64 .BuckHashSys}}</td></tr>
<tr><td class="label">GC metadata bytes</td><td class="value">{{fuint64 .GCSys}}</td></tr>
<tr><td class="label">Off heap bytes</td><td class="value">{{fuint64 .OtherSys}}</td></tr>
</table>
<h2>By size</h2>
<table>
<tr><th>Size</th><th>Mallocs</th><th>Frees</th></tr>
{{range .BySize}}<tr><td class="value">{{fuint32 .Size}}</td><td class="value">{{fuint64 .Mallocs}}</td><td class="value">{{fuint64 .Frees}}</td></tr>{{end}}
</table>
{{end}}
`))

var DebugTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}GoPls Debug pages{{end}}
{{define "body"}}
<a href="/debug/pprof">Profiling</a>
{{end}}
`))

var CacheTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Cache {{.ID}}{{end}}
{{define "body"}}
<h2>memoize.Store entries</h2>
<ul>{{range $k,$v := .MemStats}}<li>{{$k}} - {{$v}}</li>{{end}}</ul>
<h2>Per-package usage - not accurate, for guidance only</h2>
{{.PackageStats true}}
{{end}}
`))

var ClientTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Client {{.Session.ID}}{{end}}
{{define "body"}}
Using session: <b>{{template "sessionlink" .Session.ID}}</b><br>
{{if .DebugAddress}}Debug this client at: <a href="http://{{localAddress .DebugAddress}}">{{localAddress .DebugAddress}}</a><br>{{end}}
Logfile: {{.Logfile}}<br>
Gopls Path: {{.GoplsPath}}<br>
<h2>Diagnostics</h2>
{{/*Service: []protocol.Server; each server has map[uri]fileReports;
	each fileReport: map[diagnosticSoure]diagnosticReport
	diagnosticSource is one of 5 source
	diagnosticReport: snapshotID and map[hash]*source.Diagnostic
	sourceDiagnostic: struct {
		Range    protocol.Range
		Message  string
		Source   string
		Code     string
		CodeHref string
		Severity protocol.DiagnosticSeverity
		Tags     []protocol.DiagnosticTag

		Related []RelatedInformation
	}
	RelatedInformation: struct {
		URI     span.URI
		Range   protocol.Range
		Message string
	}
	*/}}
<ul>{{range $k, $v := .Service.Diagnostics}}<li>{{$k}}:<ol>{{range $v}}<li>{{.}}</li>{{end}}</ol></li>{{end}}</ul>
{{end}}
`))

var ServerTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Server {{.ID}}{{end}}
{{define "body"}}
{{if .DebugAddress}}Debug this server at: <a href="http://{{localAddress .DebugAddress}}">{{localAddress .DebugAddress}}</a><br>{{end}}
Logfile: {{.Logfile}}<br>
Gopls Path: {{.GoplsPath}}<br>
{{end}}
`))

var SessionTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Session {{.ID}}{{end}}
{{define "body"}}
From: <b>{{template "cachelink" .Cache.ID}}</b><br>
<h2>Views</h2>
<ul>{{range .Views}}<li>{{.Name}} is {{template "viewlink" .ID}} in {{.Folder}}</li>{{end}}</ul>
<h2>Overlays</h2>
<ul>{{range .Overlays}}<li>{{template "filelink" .}}</li>{{end}}</ul>
<h2>Options</h2>
{{range options .}}
<p><b>{{.Name}}</b> {{.Type}}</p>
<p><i>default:</i> {{.Default}}</p>
{{if ne .Default .Current}}<p><i>current:</i> {{.Current}}</p>{{end}}
{{end}}
{{end}}
`))

var ViewTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}View {{.ID}}{{end}}
{{define "body"}}
Name: <b>{{.Name}}</b><br>
Folder: <b>{{.Folder}}</b><br>
From: <b>{{template "sessionlink" .Session.ID}}</b><br>
<h2>Environment</h2>
<ul>{{range .Options.Env}}<li>{{.}}</li>{{end}}</ul>
{{end}}
`))

var FileTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}Overlay {{.FileIdentity.Hash}}{{end}}
{{define "body"}}
{{with .}}
	From: <b>{{template "sessionlink" .Session}}</b><br>
	URI: <b>{{.URI}}</b><br>
	Identifier: <b>{{.FileIdentity.Hash}}</b><br>
	Version: <b>{{.Version}}</b><br>
	Kind: <b>{{.Kind}}</b><br>
{{end}}
<h3>Contents</h3>
<pre>{{fcontent .Read}}</pre>
{{end}}
`))
