// 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 (
	"bytes"
	"context"
	"go/token"
	"html/template"
	stdlog "log"
	"net"
	"net/http"
	"net/http/pprof"
	_ "net/http/pprof" // pull in the standard pprof handlers
	"path"
	"runtime"
	"strconv"
	"strings"
	"sync"

	"golang.org/x/tools/internal/span"
	"golang.org/x/tools/internal/telemetry/export"
	"golang.org/x/tools/internal/telemetry/export/prometheus"
	"golang.org/x/tools/internal/telemetry/log"
	"golang.org/x/tools/internal/telemetry/tag"
)

type Cache interface {
	ID() string
	FileSet() *token.FileSet
}

type Session interface {
	ID() string
	Cache() Cache
	Files() []*File
	File(hash string) *File
}

type View interface {
	ID() string
	Name() string
	Folder() span.URI
	Session() Session
}

type File struct {
	Session Session
	URI     span.URI
	Data    string
	Error   error
	Hash    string
}

var (
	mu   sync.Mutex
	data = struct {
		Caches   []Cache
		Sessions []Session
		Views    []View
	}{}
)

// AddCache adds a cache to the set being served
func AddCache(cache Cache) {
	mu.Lock()
	defer mu.Unlock()
	data.Caches = append(data.Caches, cache)
}

// DropCache drops a cache from the set being served
func DropCache(cache Cache) {
	mu.Lock()
	defer mu.Unlock()
	//find and remove the cache
	if i, _ := findCache(cache.ID()); i >= 0 {
		copy(data.Caches[i:], data.Caches[i+1:])
		data.Caches[len(data.Caches)-1] = nil
		data.Caches = data.Caches[:len(data.Caches)-1]
	}
}

func findCache(id string) (int, Cache) {
	for i, c := range data.Caches {
		if c.ID() == id {
			return i, c
		}
	}
	return -1, nil
}

func getCache(r *http.Request) interface{} {
	mu.Lock()
	defer mu.Unlock()
	id := path.Base(r.URL.Path)
	result := struct {
		Cache
		Sessions []Session
	}{}
	_, result.Cache = findCache(id)

	// now find all the views that belong to this session
	for _, v := range data.Sessions {
		if v.Cache().ID() == id {
			result.Sessions = append(result.Sessions, v)
		}
	}
	return result
}

func findSession(id string) Session {
	for _, c := range data.Sessions {
		if c.ID() == id {
			return c
		}
	}
	return nil
}

func getSession(r *http.Request) interface{} {
	mu.Lock()
	defer mu.Unlock()
	id := path.Base(r.URL.Path)
	result := struct {
		Session
		Views []View
	}{
		Session: findSession(id),
	}
	// now find all the views that belong to this session
	for _, v := range data.Views {
		if v.Session().ID() == id {
			result.Views = append(result.Views, v)
		}
	}
	return result
}

func findView(id string) View {
	for _, c := range data.Views {
		if c.ID() == id {
			return c
		}
	}
	return nil
}

func getView(r *http.Request) interface{} {
	mu.Lock()
	defer mu.Unlock()
	id := path.Base(r.URL.Path)
	return findView(id)
}

func getFile(r *http.Request) interface{} {
	mu.Lock()
	defer mu.Unlock()
	hash := path.Base(r.URL.Path)
	sid := path.Base(path.Dir(r.URL.Path))
	session := findSession(sid)
	return session.File(hash)
}

func getInfo(r *http.Request) interface{} {
	buf := &bytes.Buffer{}
	PrintVersionInfo(buf, true, HTML)
	return template.HTML(buf.String())
}

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

// AddSession adds a session to the set being served
func AddSession(session Session) {
	mu.Lock()
	defer mu.Unlock()
	data.Sessions = append(data.Sessions, session)
}

// DropSession drops a session from the set being served
func DropSession(session Session) {
	mu.Lock()
	defer mu.Unlock()
	//find and remove the session
}

// AddView adds a view to the set being served
func AddView(view View) {
	mu.Lock()
	defer mu.Unlock()
	data.Views = append(data.Views, view)
}

// DropView drops a view from the set being served
func DropView(view View) {
	mu.Lock()
	defer mu.Unlock()
	//find and remove the view
}

// Serve starts and runs a debug server in the background.
// It also logs the port the server starts on, to allow for :0 auto assigned
// ports.
func Serve(ctx context.Context, addr string) error {
	mu.Lock()
	defer mu.Unlock()
	if addr == "" {
		return nil
	}
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		return err
	}

	port := listener.Addr().(*net.TCPAddr).Port
	if strings.HasSuffix(addr, ":0") {
		stdlog.Printf("debug server listening on port %d", port)
	}
	log.Print(ctx, "Debug serving", tag.Of("Port", port))
	prometheus := prometheus.New()
	rpcs := &rpcs{}
	traces := &traces{}
	export.AddExporters(prometheus, rpcs, traces)
	go func() {
		mux := http.NewServeMux()
		mux.HandleFunc("/", Render(mainTmpl, func(*http.Request) interface{} { return data }))
		mux.HandleFunc("/debug/", Render(debugTmpl, nil))
		mux.HandleFunc("/debug/pprof/", pprof.Index)
		mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
		mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
		mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
		mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
		mux.HandleFunc("/metrics/", prometheus.Serve)
		mux.HandleFunc("/rpc/", Render(rpcTmpl, rpcs.getData))
		mux.HandleFunc("/trace/", Render(traceTmpl, traces.getData))
		mux.HandleFunc("/cache/", Render(cacheTmpl, getCache))
		mux.HandleFunc("/session/", Render(sessionTmpl, getSession))
		mux.HandleFunc("/view/", Render(viewTmpl, getView))
		mux.HandleFunc("/file/", Render(fileTmpl, getFile))
		mux.HandleFunc("/info", Render(infoTmpl, getInfo))
		mux.HandleFunc("/memory", Render(memoryTmpl, getMemory))
		if err := http.Serve(listener, mux); err != nil {
			log.Error(ctx, "Debug server failed", err)
			return
		}
		log.Print(ctx, "Debug server finished")
	}()
	return nil
}

func Render(tmpl *template.Template, fun func(*http.Request) interface{}) 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 {
			log.Error(context.Background(), "", err)
		}
	}
}

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))
}

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 "sessionlink"}}<a href="/session/{{.}}">Session {{.}}</a>{{end}}
{{define "viewlink"}}<a href="/view/{{.}}">View {{.}}</a>{{end}}
{{define "filelink"}}<a href="/file/{{.Session.ID}}/{{.Hash}}">{{.URI}}</a>{{end}}
`)).Funcs(template.FuncMap{
	"fuint64": fuint64,
	"fuint32": fuint32,
})

var mainTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}GoPls server information{{end}}
{{define "body"}}
<h2>Caches</h2>
<ul>{{range .Caches}}<li>{{template "cachelink" .ID}}</li>{{end}}</ul>
<h2>Sessions</h2>
<ul>{{range .Sessions}}<li>{{template "sessionlink" .ID}} from {{template "cachelink" .Cache.ID}}</li>{{end}}</ul>
<h2>Views</h2>
<ul>{{range .Views}}<li>{{.Name}} is {{template "viewlink" .ID}} from {{template "sessionlink" .Session.ID}} in {{.Folder}}</li>{{end}}</ul>
{{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>Sessions</h2>
<ul>{{range .Sessions}}<li>{{template "sessionlink" .ID}}</li>{{end}}</ul>
{{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>Files</h2>
<ul>{{range .Files}}<li>{{template "filelink" .}}</li>{{end}}</ul>
{{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 .Env}}<li>{{.}}</li>{{end}}</ul>
{{end}}
`))

var fileTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
{{define "title"}}File {{.Hash}}{{end}}
{{define "body"}}
From: <b>{{template "sessionlink" .Session.ID}}</b><br>
URI: <b>{{.URI}}</b><br>
Hash: <b>{{.Hash}}</b><br>
Error: <b>{{.Error}}</b><br>
<h3>Contents</h3>
<pre>{{.Data}}</pre>
{{end}}
`))
