// 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 logopt

import (
	"cmd/internal/obj"
	"cmd/internal/objabi"
	"cmd/internal/src"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/url"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"sync"
	"unicode"
)

// This implements (non)optimization logging for -json option to the Go compiler
// The option is -json 0,<destination>.
//
// 0 is the version number; to avoid the need for synchronized updates, if
// new versions of the logging appear, the compiler will support both, for a while,
// and clients will specify what they need.
//
// <destination> is a directory.
// Directories are specified with a leading / or os.PathSeparator,
// or more explicitly with file://directory.  The second form is intended to
// deal with corner cases on Windows, and to allow specification of a relative
// directory path (which is normally a bad idea, because the local directory
// varies a lot in a build, especially with modules and/or vendoring, and may
// not be writeable).
//
// For each package pkg compiled, a url.PathEscape(pkg)-named subdirectory
// is created.  For each source file.go in that package that generates
// diagnostics (no diagnostics means no file),
// a url.PathEscape(file)+".json"-named file is created and contains the
// logged diagnostics.
//
// For example, "cmd%2Finternal%2Fdwarf/%3Cautogenerated%3E.json"
// for "cmd/internal/dwarf" and <autogenerated> (which is not really a file, but the compiler sees it)
//
// If the package string is empty, it is replaced internally with string(0) which encodes to %00.
//
// Each log file begins with a JSON record identifying version,
// platform, and other context, followed by optimization-relevant
// LSP Diagnostic records, one per line (LSP version 3.15, no difference from 3.14 on the subset used here
// see https://microsoft.github.io/language-server-protocol/specifications/specification-3-15/ )
//
// The fields of a Diagnostic are used in the following way:
// Range: the outermost source position, for now begin and end are equal.
// Severity: (always) SeverityInformation (3)
// Source: (always) "go compiler"
// Code: a string describing the missed optimization, e.g., "nilcheck", "cannotInline", "isInBounds", "escape"
// Message: depending on code, additional information, e.g., the reason a function cannot be inlined.
// RelatedInformation: if the missed optimization actually occurred at a function inlined at Range,
//    then the sequence of inlined locations appears here, from (second) outermost to innermost,
//    each with message="inlineLoc".
//
//    In the case of escape analysis explanations, after any outer inlining locations,
//    the lines of the explanation appear, each potentially followed with its own inlining
//    location if the escape flow occurred within an inlined function.
//
// For example <destination>/cmd%2Fcompile%2Finternal%2Fssa/prove.json
// might begin with the following line (wrapped for legibility):
//
// {"version":0,"package":"cmd/compile/internal/ssa","goos":"darwin","goarch":"amd64",
//  "gc_version":"devel +e1b9a57852 Fri Nov 1 15:07:00 2019 -0400",
//  "file":"/Users/drchase/work/go/src/cmd/compile/internal/ssa/prove.go"}
//
// and later contain (also wrapped for legibility):
//
// {"range":{"start":{"line":191,"character":24},"end":{"line":191,"character":24}},
//  "severity":3,"code":"nilcheck","source":"go compiler","message":"",
//  "relatedInformation":[
//    {"location":{"uri":"file:///Users/drchase/work/go/src/cmd/compile/internal/ssa/func.go",
//                 "range":{"start":{"line":153,"character":16},"end":{"line":153,"character":16}}},
//     "message":"inlineLoc"}]}
//
// That is, at prove.go (implicit from context, provided in both filename and header line),
// line 191, column 24, a nilcheck occurred in the generated code.
// The relatedInformation indicates that this code actually came from
// an inlined call to func.go, line 153, character 16.
//
// prove.go:191:
// 	ft.orderS = f.newPoset()
// func.go:152 and 153:
//  func (f *Func) newPoset() *poset {
//	    if len(f.Cache.scrPoset) > 0 {
//
// In the case that the package is empty, the string(0) package name is also used in the header record, for example
//
//  go tool compile -json=0,file://logopt x.go       # no -p option to set the package
//  head -1 logopt/%00/x.json
//  {"version":0,"package":"\u0000","goos":"darwin","goarch":"amd64","gc_version":"devel +86487adf6a Thu Nov 7 19:34:56 2019 -0500","file":"x.go"}

type VersionHeader struct {
	Version   int    `json:"version"`
	Package   string `json:"package"`
	Goos      string `json:"goos"`
	Goarch    string `json:"goarch"`
	GcVersion string `json:"gc_version"`
	File      string `json:"file,omitempty"` // LSP requires an enclosing resource, i.e., a file
}

// DocumentURI, Position, Range, Location, Diagnostic, DiagnosticRelatedInformation all reuse json definitions from gopls.
// See https://github.com/golang/tools/blob/22afafe3322a860fcd3d88448768f9db36f8bc5f/internal/lsp/protocol/tsprotocol.go

type DocumentURI string

type Position struct {
	Line      uint `json:"line"`      // gopls uses float64, but json output is the same for integers
	Character uint `json:"character"` // gopls uses float64, but json output is the same for integers
}

// A Range in a text document expressed as (zero-based) start and end positions.
// A range is comparable to a selection in an editor. Therefore the end position is exclusive.
// If you want to specify a range that contains a line including the line ending character(s)
// then use an end position denoting the start of the next line.
type Range struct {
	/*Start defined:
	 * The range's start position
	 */
	Start Position `json:"start"`

	/*End defined:
	 * The range's end position
	 */
	End Position `json:"end"` // exclusive
}

// A Location represents a location inside a resource, such as a line inside a text file.
type Location struct {
	// URI is
	URI DocumentURI `json:"uri"`

	// Range is
	Range Range `json:"range"`
}

/* DiagnosticRelatedInformation defined:
 * Represents a related message and source code location for a diagnostic. This should be
 * used to point to code locations that cause or related to a diagnostics, e.g when duplicating
 * a symbol in a scope.
 */
type DiagnosticRelatedInformation struct {

	/*Location defined:
	 * The location of this related diagnostic information.
	 */
	Location Location `json:"location"`

	/*Message defined:
	 * The message of this related diagnostic information.
	 */
	Message string `json:"message"`
}

// DiagnosticSeverity defines constants
type DiagnosticSeverity uint

const (
	/*SeverityInformation defined:
	 * Reports an information.
	 */
	SeverityInformation DiagnosticSeverity = 3
)

// DiagnosticTag defines constants
type DiagnosticTag uint

/*Diagnostic defined:
 * Represents a diagnostic, such as a compiler error or warning. Diagnostic objects
 * are only valid in the scope of a resource.
 */
type Diagnostic struct {

	/*Range defined:
	 * The range at which the message applies
	 */
	Range Range `json:"range"`

	/*Severity defined:
	 * The diagnostic's severity. Can be omitted. If omitted it is up to the
	 * client to interpret diagnostics as error, warning, info or hint.
	 */
	Severity DiagnosticSeverity `json:"severity,omitempty"` // always SeverityInformation for optimizer logging.

	/*Code defined:
	 * The diagnostic's code, which usually appear in the user interface.
	 */
	Code string `json:"code,omitempty"` // LSP uses 'number | string' = gopls interface{}, but only string here, e.g. "boundsCheck", "nilcheck", etc.

	/*Source defined:
	 * A human-readable string describing the source of this
	 * diagnostic, e.g. 'typescript' or 'super lint'. It usually
	 * appears in the user interface.
	 */
	Source string `json:"source,omitempty"` // "go compiler"

	/*Message defined:
	 * The diagnostic's message. It usually appears in the user interface
	 */
	Message string `json:"message"` // sometimes used, provides additional information.

	/*Tags defined:
	 * Additional metadata about the diagnostic.
	 */
	Tags []DiagnosticTag `json:"tags,omitempty"` // always empty for logging optimizations.

	/*RelatedInformation defined:
	 * An array of related diagnostic information, e.g. when symbol-names within
	 * a scope collide all definitions can be marked via this property.
	 */
	RelatedInformation []DiagnosticRelatedInformation `json:"relatedInformation,omitempty"`
}

// A LoggedOpt is what the compiler produces and accumulates,
// to be converted to JSON for human or IDE consumption.
type LoggedOpt struct {
	pos          src.XPos      // Source code position at which the event occurred. If it is inlined, outer and all inlined locations will appear in JSON.
	compilerPass string        // Compiler pass.  For human/adhoc consumption; does not appear in JSON (yet)
	functionName string        // Function name.  For human/adhoc consumption; does not appear in JSON (yet)
	what         string        // The (non) optimization; "nilcheck", "boundsCheck", "inline", "noInline"
	target       []interface{} // Optional target(s) or parameter(s) of "what" -- what was inlined, why it was not, size of copy, etc. 1st is most important/relevant.
}

type logFormat uint8

const (
	None  logFormat = iota
	Json0           // version 0 for LSP 3.14, 3.15; future versions of LSP may change the format and the compiler may need to support both as clients are updated.
)

var Format = None
var dest string

// LogJsonOption parses and validates the version,directory value attached to the -json compiler flag.
func LogJsonOption(flagValue string) {
	version, directory := parseLogFlag("json", flagValue)
	if version != 0 {
		log.Fatal("-json version must be 0")
	}
	dest = checkLogPath(directory)
	Format = Json0
}

// parseLogFlag checks the flag passed to -json
// for version,destination format and returns the two parts.
func parseLogFlag(flag, value string) (version int, directory string) {
	if Format != None {
		log.Fatal("Cannot repeat -json flag")
	}
	commaAt := strings.Index(value, ",")
	if commaAt <= 0 {
		log.Fatalf("-%s option should be '<version>,<destination>' where <version> is a number", flag)
	}
	v, err := strconv.Atoi(value[:commaAt])
	if err != nil {
		log.Fatalf("-%s option should be '<version>,<destination>' where <version> is a number: err=%v", flag, err)
	}
	version = v
	directory = value[commaAt+1:]
	return
}

// isWindowsDriveURI returns true if the file URI is of the format used by
// Windows URIs. The url.Parse package does not specially handle Windows paths
// (see golang/go#6027), so we check if the URI path has a drive prefix (e.g. "/C:").
// (copied from tools/internal/span/uri.go)
// this is less comprehensive that the processing in filepath.IsAbs on Windows.
func isWindowsDriveURIPath(uri string) bool {
	if len(uri) < 4 {
		return false
	}
	return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':'
}

func parseLogPath(destination string) (string, string) {
	if filepath.IsAbs(destination) {
		return filepath.Clean(destination), ""
	}
	if strings.HasPrefix(destination, "file://") { // IKWIAD, or Windows C:\foo\bar\baz
		uri, err := url.Parse(destination)
		if err != nil {
			return "", fmt.Sprintf("optimizer logging destination looked like file:// URI but failed to parse: err=%v", err)
		}
		destination = uri.Host + uri.Path
		if isWindowsDriveURIPath(destination) {
			// strip leading / from /C:
			// unlike tools/internal/span/uri.go, do not uppercase the drive letter -- let filepath.Clean do what it does.
			destination = destination[1:]
		}
		return filepath.Clean(destination), ""
	}
	return "", fmt.Sprintf("optimizer logging destination %s was neither %s-prefixed directory nor file://-prefixed file URI", destination, string(filepath.Separator))
}

// checkLogPath does superficial early checking of the string specifying
// the directory to which optimizer logging is directed, and if
// it passes the test, stores the string in LO_dir
func checkLogPath(destination string) string {
	path, complaint := parseLogPath(destination)
	if complaint != "" {
		log.Fatalf(complaint)
	}
	err := os.MkdirAll(path, 0755)
	if err != nil {
		log.Fatalf("optimizer logging destination '<version>,<directory>' but could not create <directory>: err=%v", err)
	}
	return path
}

var loggedOpts []*LoggedOpt
var mu = sync.Mutex{} // mu protects loggedOpts.

// NewLoggedOpt allocates a new LoggedOpt, to later be passed to either NewLoggedOpt or LogOpt as "args".
// Pos is the source position (including inlining), what is the message, pass is which pass created the message,
// funcName is the name of the function
// A typical use for this to accumulate an explanation for a missed optimization, for example, why did something escape?
func NewLoggedOpt(pos src.XPos, what, pass, funcName string, args ...interface{}) *LoggedOpt {
	pass = strings.Replace(pass, " ", "_", -1)
	return &LoggedOpt{pos, pass, funcName, what, args}
}

// Logopt logs information about a (usually missed) optimization performed by the compiler.
// Pos is the source position (including inlining), what is the message, pass is which pass created the message,
// funcName is the name of the function
func LogOpt(pos src.XPos, what, pass, funcName string, args ...interface{}) {
	if Format == None {
		return
	}
	lo := NewLoggedOpt(pos, what, pass, funcName, args...)
	mu.Lock()
	defer mu.Unlock()
	// Because of concurrent calls from back end, no telling what the order will be, but is stable-sorted by outer Pos before use.
	loggedOpts = append(loggedOpts, lo)
}

// Enabled returns whether optimization logging is enabled.
func Enabled() bool {
	switch Format {
	case None:
		return false
	case Json0:
		return true
	}
	panic("Unexpected optimizer-logging level")
}

// byPos sorts diagnostics by source position.
type byPos struct {
	ctxt *obj.Link
	a    []*LoggedOpt
}

func (x byPos) Len() int { return len(x.a) }
func (x byPos) Less(i, j int) bool {
	return x.ctxt.OutermostPos(x.a[i].pos).Before(x.ctxt.OutermostPos(x.a[j].pos))
}
func (x byPos) Swap(i, j int) { x.a[i], x.a[j] = x.a[j], x.a[i] }

func writerForLSP(subdirpath, file string) io.WriteCloser {
	basename := file
	lastslash := strings.LastIndexAny(basename, "\\/")
	if lastslash != -1 {
		basename = basename[lastslash+1:]
	}
	lastdot := strings.LastIndex(basename, ".go")
	if lastdot != -1 {
		basename = basename[:lastdot]
	}
	basename = pathEscape(basename)

	// Assume a directory, make a file
	p := filepath.Join(subdirpath, basename+".json")
	w, err := os.Create(p)
	if err != nil {
		log.Fatalf("Could not create file %s for logging optimizer actions, %v", p, err)
	}
	return w
}

func fixSlash(f string) string {
	if os.PathSeparator == '/' {
		return f
	}
	return strings.Replace(f, string(os.PathSeparator), "/", -1)
}

func uriIfy(f string) DocumentURI {
	url := url.URL{
		Scheme: "file",
		Path:   fixSlash(f),
	}
	return DocumentURI(url.String())
}

// Return filename, replacing a first occurrence of $GOROOT with the
// actual value of the GOROOT (because LSP does not speak "$GOROOT").
func uprootedPath(filename string) string {
	if !strings.HasPrefix(filename, "$GOROOT/") {
		return filename
	}
	return objabi.GOROOT + filename[len("$GOROOT"):]
}

// FlushLoggedOpts flushes all the accumulated optimization log entries.
func FlushLoggedOpts(ctxt *obj.Link, slashPkgPath string) {
	if Format == None {
		return
	}

	sort.Stable(byPos{ctxt, loggedOpts}) // Stable is necessary to preserve the per-function order, which is repeatable.
	switch Format {

	case Json0: // LSP 3.15
		var posTmp []src.Pos
		var encoder *json.Encoder
		var w io.WriteCloser

		if slashPkgPath == "" {
			slashPkgPath = "\000"
		}
		subdirpath := filepath.Join(dest, pathEscape(slashPkgPath))
		err := os.MkdirAll(subdirpath, 0755)
		if err != nil {
			log.Fatalf("Could not create directory %s for logging optimizer actions, %v", subdirpath, err)
		}
		diagnostic := Diagnostic{Source: "go compiler", Severity: SeverityInformation}

		// For LSP, make a subdirectory for the package, and for each file foo.go, create foo.json in that subdirectory.
		currentFile := ""
		for _, x := range loggedOpts {
			posTmp, p0 := x.parsePos(ctxt, posTmp)
			p0f := uprootedPath(p0.Filename())

			if currentFile != p0f {
				if w != nil {
					w.Close()
				}
				currentFile = p0f
				w = writerForLSP(subdirpath, currentFile)
				encoder = json.NewEncoder(w)
				encoder.Encode(VersionHeader{Version: 0, Package: slashPkgPath, Goos: objabi.GOOS, Goarch: objabi.GOARCH, GcVersion: objabi.Version, File: currentFile})
			}

			// The first "target" is the most important one.
			var target string
			if len(x.target) > 0 {
				target = fmt.Sprint(x.target[0])
			}

			diagnostic.Code = x.what
			diagnostic.Message = target
			diagnostic.Range = newPointRange(p0)
			diagnostic.RelatedInformation = diagnostic.RelatedInformation[:0]

			appendInlinedPos(posTmp, &diagnostic)

			// Diagnostic explanation is stored in RelatedInformation after inlining info
			if len(x.target) > 1 {
				switch y := x.target[1].(type) {
				case []*LoggedOpt:
					for _, z := range y {
						posTmp, p0 := z.parsePos(ctxt, posTmp)
						loc := newLocation(p0)
						msg := z.what
						if len(z.target) > 0 {
							msg = msg + ": " + fmt.Sprint(z.target[0])
						}

						diagnostic.RelatedInformation = append(diagnostic.RelatedInformation, DiagnosticRelatedInformation{Location: loc, Message: msg})
						appendInlinedPos(posTmp, &diagnostic)
					}
				}
			}

			encoder.Encode(diagnostic)
		}
		if w != nil {
			w.Close()
		}
	}
}

// newPointRange returns a single-position Range for the compiler source location p.
func newPointRange(p src.Pos) Range {
	return Range{Start: Position{p.Line(), p.Col()},
		End: Position{p.Line(), p.Col()}}
}

// newLocation returns the Location for the compiler source location p
func newLocation(p src.Pos) Location {
	loc := Location{URI: uriIfy(uprootedPath(p.Filename())), Range: newPointRange(p)}
	return loc
}

// appendInlinedPos extracts inlining information from posTmp and append it to diagnostic
func appendInlinedPos(posTmp []src.Pos, diagnostic *Diagnostic) {
	for i := 1; i < len(posTmp); i++ {
		p := posTmp[i]
		loc := newLocation(p)
		diagnostic.RelatedInformation = append(diagnostic.RelatedInformation, DiagnosticRelatedInformation{Location: loc, Message: "inlineLoc"})
	}
}

func (x *LoggedOpt) parsePos(ctxt *obj.Link, posTmp []src.Pos) ([]src.Pos, src.Pos) {
	posTmp = ctxt.AllPos(x.pos, posTmp)
	// Reverse posTmp to put outermost first.
	l := len(posTmp)
	for i := 0; i < l/2; i++ {
		posTmp[i], posTmp[l-i-1] = posTmp[l-i-1], posTmp[i]
	}
	p0 := posTmp[0]
	return posTmp, p0
}
