// 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 sortslice defines an Analyzer that checks for calls
// to sort.Slice that do not use a slice type as first argument.
package sortslice

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"go/types"

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

const Doc = `check the argument type of sort.Slice

sort.Slice requires an argument of a slice type. Check that
the interface{} value passed to sort.Slice is actually a slice.`

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

func run(pass *analysis.Pass) (interface{}, error) {
	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.Callee(pass.TypesInfo, call).(*types.Func)
		if fn == nil {
			return
		}

		if fn.FullName() != "sort.Slice" {
			return
		}

		arg := call.Args[0]
		typ := pass.TypesInfo.Types[arg].Type
		switch typ.Underlying().(type) {
		case *types.Slice, *types.Interface:
			return
		}

		var fixes []analysis.SuggestedFix
		switch v := typ.Underlying().(type) {
		case *types.Array:
			var buf bytes.Buffer
			format.Node(&buf, pass.Fset, &ast.SliceExpr{
				X:      arg,
				Slice3: false,
				Lbrack: arg.End() + 1,
				Rbrack: arg.End() + 3,
			})
			fixes = append(fixes, analysis.SuggestedFix{
				Message: "Get a slice of the full array",
				TextEdits: []analysis.TextEdit{{
					Pos:     arg.Pos(),
					End:     arg.End(),
					NewText: buf.Bytes(),
				}},
			})
		case *types.Pointer:
			_, ok := v.Elem().Underlying().(*types.Slice)
			if !ok {
				break
			}
			var buf bytes.Buffer
			format.Node(&buf, pass.Fset, &ast.StarExpr{
				X: arg,
			})
			fixes = append(fixes, analysis.SuggestedFix{
				Message: "Dereference the pointer to the slice",
				TextEdits: []analysis.TextEdit{{
					Pos:     arg.Pos(),
					End:     arg.End(),
					NewText: buf.Bytes(),
				}},
			})
		case *types.Signature:
			if v.Params().Len() != 0 || v.Results().Len() != 1 {
				break
			}
			if _, ok := v.Results().At(0).Type().Underlying().(*types.Slice); !ok {
				break
			}
			var buf bytes.Buffer
			format.Node(&buf, pass.Fset, &ast.CallExpr{
				Fun: arg,
			})
			fixes = append(fixes, analysis.SuggestedFix{
				Message: "Call the function",
				TextEdits: []analysis.TextEdit{{
					Pos:     arg.Pos(),
					End:     arg.End(),
					NewText: buf.Bytes(),
				}},
			})
		}

		pass.Report(analysis.Diagnostic{
			Pos:            call.Pos(),
			End:            call.End(),
			Message:        fmt.Sprintf("sort.Slice's argument must be a slice; is called with %s", typ.String()),
			SuggestedFixes: fixes,
		})
	})
	return nil, nil
}
