// Copyright 2018 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 unmarshal

import (
	_ "embed"
	"go/ast"
	"go/types"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/inspect"
	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/go/types/typeutil"
	"golang.org/x/tools/internal/typeparams"
)

//go:embed doc.go
var doc string

var Analyzer = &analysis.Analyzer{
	Name:     "unmarshal",
	Doc:      analysisutil.MustExtractDoc(doc, "unmarshal"),
	URL:      "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/unmarshal",
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

func run(pass *analysis.Pass) (interface{}, error) {
	switch pass.Pkg.Path() {
	case "encoding/gob", "encoding/json", "encoding/xml", "encoding/asn1":
		// These packages know how to use their own APIs.
		// Sometimes they are testing what happens to incorrect programs.
		return nil, nil
	}

	// Note: (*"encoding/json".Decoder).Decode, (* "encoding/gob".Decoder).Decode
	// and (* "encoding/xml".Decoder).Decode are methods and can be a typeutil.Callee
	// without directly importing their packages. So we cannot just skip this package
	// when !analysisutil.Imports(pass.Pkg, "encoding/...").
	// TODO(taking): Consider using a prepass to collect typeutil.Callees.

	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

	nodeFilter := []ast.Node{
		(*ast.CallExpr)(nil),
	}
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		call := n.(*ast.CallExpr)
		fn := typeutil.StaticCallee(pass.TypesInfo, call)
		if fn == nil {
			return // not a static call
		}

		// Classify the callee (without allocating memory).
		argidx := -1

		recv := fn.Type().(*types.Signature).Recv()
		if fn.Name() == "Unmarshal" && recv == nil {
			// "encoding/json".Unmarshal
			// "encoding/xml".Unmarshal
			// "encoding/asn1".Unmarshal
			switch fn.Pkg().Path() {
			case "encoding/json", "encoding/xml", "encoding/asn1":
				argidx = 1 // func([]byte, interface{})
			}
		} else if fn.Name() == "Decode" && recv != nil {
			// (*"encoding/json".Decoder).Decode
			// (* "encoding/gob".Decoder).Decode
			// (* "encoding/xml".Decoder).Decode
			t := recv.Type()
			if ptr, ok := t.(*types.Pointer); ok {
				t = ptr.Elem()
			}
			tname := t.(*types.Named).Obj()
			if tname.Name() == "Decoder" {
				switch tname.Pkg().Path() {
				case "encoding/json", "encoding/xml", "encoding/gob":
					argidx = 0 // func(interface{})
				}
			}
		}
		if argidx < 0 {
			return // not a function we are interested in
		}

		if len(call.Args) < argidx+1 {
			return // not enough arguments, e.g. called with return values of another function
		}

		t := pass.TypesInfo.Types[call.Args[argidx]].Type
		switch t.Underlying().(type) {
		case *types.Pointer, *types.Interface, *typeparams.TypeParam:
			return
		}

		switch argidx {
		case 0:
			pass.Reportf(call.Lparen, "call of %s passes non-pointer", fn.Name())
		case 1:
			pass.Reportf(call.Lparen, "call of %s passes non-pointer as second argument", fn.Name())
		}
	})
	return nil, nil
}
