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