// Copyright 2020 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 source

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/span"
)

func GCOptimizationDetails(ctx context.Context, snapshot Snapshot, pkgDir span.URI) (map[VersionedFileIdentity][]*Diagnostic, error) {
	outDir := filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.details", os.Getpid()))
	if err := os.MkdirAll(outDir, 0700); err != nil {
		return nil, err
	}
	tmpFile, err := ioutil.TempFile(os.TempDir(), "gopls-x")
	if err != nil {
		return nil, err
	}
	defer os.Remove(tmpFile.Name())
	args := []string{fmt.Sprintf("-gcflags=-json=0,%s", outDir),
		fmt.Sprintf("-o=%s", tmpFile.Name()),
		pkgDir.Filename(),
	}
	err = snapshot.RunGoCommandDirect(ctx, "build", args)
	if err != nil {
		return nil, err
	}
	files, err := findJSONFiles(outDir)
	if err != nil {
		return nil, err
	}
	reports := make(map[VersionedFileIdentity][]*Diagnostic)
	opts := snapshot.View().Options()
	var parseError error
	for _, fn := range files {
		fname, v, err := parseDetailsFile(fn)
		if err != nil {
			// expect errors for all the files, save 1
			parseError = err
		}
		if !strings.HasSuffix(fname, ".go") {
			continue // <autogenerated>
		}
		uri := span.URIFromPath(fname)
		x := snapshot.FindFile(uri)
		if x == nil {
			continue
		}
		v = filterDiagnostics(v, &opts)
		reports[x.VersionedFileIdentity()] = v
	}
	return reports, parseError
}

func filterDiagnostics(v []*Diagnostic, o *Options) []*Diagnostic {
	var ans []*Diagnostic
	for _, x := range v {
		if x.Source != "go compiler" {
			continue
		}
		if o.Annotations["noInline"] &&
			(strings.HasPrefix(x.Message, "canInline") ||
				strings.HasPrefix(x.Message, "cannotInline") ||
				strings.HasPrefix(x.Message, "inlineCall")) {
			continue
		} else if o.Annotations["noEscape"] &&
			(strings.HasPrefix(x.Message, "escape") || x.Message == "leak") {
			continue
		} else if o.Annotations["noNilcheck"] && strings.HasPrefix(x.Message, "nilcheck") {
			continue
		} else if o.Annotations["noBounds"] &&
			(strings.HasPrefix(x.Message, "isInBounds") ||
				strings.HasPrefix(x.Message, "isSliceInBounds")) {
			continue
		}
		ans = append(ans, x)
	}
	return ans
}

func parseDetailsFile(fn string) (string, []*Diagnostic, error) {
	buf, err := ioutil.ReadFile(fn)
	if err != nil {
		return "", nil, err // This is an internal error. Likely ever file will fail.
	}
	var fname string
	var ans []*Diagnostic
	lines := bytes.Split(buf, []byte{'\n'})
	for i, l := range lines {
		if len(l) == 0 {
			continue
		}
		if i == 0 {
			x := make(map[string]interface{})
			if err := json.Unmarshal(l, &x); err != nil {
				return "", nil, fmt.Errorf("internal error (%v) parsing first line of json file %s",
					err, fn)
			}
			fname = x["file"].(string)
			continue
		}
		y := protocol.Diagnostic{}
		if err := json.Unmarshal(l, &y); err != nil {
			return "", nil, fmt.Errorf("internal error (%#v) parsing json file for %s", err, fname)
		}
		y.Range.Start.Line-- // change from 1-based to 0-based
		y.Range.Start.Character--
		y.Range.End.Line--
		y.Range.End.Character--
		msg := y.Code.(string)
		if y.Message != "" {
			msg = fmt.Sprintf("%s(%s)", msg, y.Message)
		}
		x := Diagnostic{
			Range:    y.Range,
			Message:  msg,
			Source:   y.Source,
			Severity: y.Severity,
		}
		for _, ri := range y.RelatedInformation {
			x.Related = append(x.Related, RelatedInformation{
				URI:     ri.Location.URI.SpanURI(),
				Range:   ri.Location.Range,
				Message: ri.Message,
			})
		}
		ans = append(ans, &x)
	}
	return fname, ans, nil
}

func findJSONFiles(dir string) ([]string, error) {
	ans := []string{}
	f := func(path string, fi os.FileInfo, err error) error {
		if fi.IsDir() {
			return nil
		}
		if strings.HasSuffix(path, ".json") {
			ans = append(ans, path)
		}
		return nil
	}
	err := filepath.Walk(dir, f)
	return ans, err
}
