// Copyright 2015 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 unusedresult defines an analyzer that checks for unused
// results of calls to certain pure functions.
package unusedresult

import (
	"go/ast"
	"go/token"
	"go/types"
	"sort"
	"strings"

	"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/internal/typeparams"
)

// TODO(adonovan): make this analysis modular: export a mustUseResult
// fact for each function that tail-calls one of the functions that we
// check, and check those functions too.

const Doc = `check for unused results of calls to some functions

Some functions like fmt.Errorf return a result and have no side effects,
so it is always a mistake to discard the result. This analyzer reports
calls to certain functions in which the result of the call is ignored.

The set of functions may be controlled using flags.`

var Analyzer = &analysis.Analyzer{
	Name:     "unusedresult",
	Doc:      Doc,
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

// flags
var funcs, stringMethods stringSetFlag

func init() {
	// TODO(adonovan): provide a comment syntax to allow users to
	// add their functions to this set using facts.
	funcs.Set("errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint,sort.Reverse,context.WithValue,context.WithCancel,context.WithDeadline,context.WithTimeout")
	Analyzer.Flags.Var(&funcs, "funcs",
		"comma-separated list of functions whose results must be used")

	stringMethods.Set("Error,String")
	Analyzer.Flags.Var(&stringMethods, "stringmethods",
		"comma-separated list of names of methods of type func() string whose results must be used")
}

func run(pass *analysis.Pass) (interface{}, error) {
	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

	nodeFilter := []ast.Node{
		(*ast.ExprStmt)(nil),
	}
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		call, ok := analysisutil.Unparen(n.(*ast.ExprStmt).X).(*ast.CallExpr)
		if !ok {
			return // not a call statement
		}
		fun := analysisutil.Unparen(call.Fun)

		if pass.TypesInfo.Types[fun].IsType() {
			return // a conversion, not a call
		}

		x, _, _, _ := typeparams.UnpackIndexExpr(fun)
		if x != nil {
			fun = x // If this is generic function or method call, skip the instantiation arguments
		}

		selector, ok := fun.(*ast.SelectorExpr)
		if !ok {
			return // neither a method call nor a qualified ident
		}

		sel, ok := pass.TypesInfo.Selections[selector]
		if ok && sel.Kind() == types.MethodVal {
			// method (e.g. foo.String())
			obj := sel.Obj().(*types.Func)
			sig := sel.Type().(*types.Signature)
			if types.Identical(sig, sigNoArgsStringResult) {
				if stringMethods[obj.Name()] {
					pass.Reportf(call.Lparen, "result of (%s).%s call not used",
						sig.Recv().Type(), obj.Name())
				}
			}
		} else if !ok {
			// package-qualified function (e.g. fmt.Errorf)
			obj := pass.TypesInfo.Uses[selector.Sel]
			if obj, ok := obj.(*types.Func); ok {
				qname := obj.Pkg().Path() + "." + obj.Name()
				if funcs[qname] {
					pass.Reportf(call.Lparen, "result of %v call not used", qname)
				}
			}
		}
	})
	return nil, nil
}

// func() string
var sigNoArgsStringResult = types.NewSignature(nil, nil,
	types.NewTuple(types.NewVar(token.NoPos, nil, "", types.Typ[types.String])),
	false)

type stringSetFlag map[string]bool

func (ss *stringSetFlag) String() string {
	var items []string
	for item := range *ss {
		items = append(items, item)
	}
	sort.Strings(items)
	return strings.Join(items, ",")
}

func (ss *stringSetFlag) Set(s string) error {
	m := make(map[string]bool) // clobber previous value
	if s != "" {
		for _, name := range strings.Split(s, ",") {
			if name == "" {
				continue // TODO: report error? proceed?
			}
			m[name] = true
		}
	}
	*ss = m
	return nil
}
