// 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 undeclaredname defines an Analyzer that applies suggested fixes
// to errors of the type "undeclared name: %s".
package undeclaredname

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

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/ast/astutil"
	"golang.org/x/tools/internal/analysisinternal"
)

const Doc = `suggested fixes for "undeclared name: <>"

This checker provides suggested fixes for type errors of the
type "undeclared name: <>". It will insert a new statement:
"<> := ".`

var Analyzer = &analysis.Analyzer{
	Name:             string(analysisinternal.UndeclaredName),
	Doc:              Doc,
	Requires:         []*analysis.Analyzer{},
	Run:              run,
	RunDespiteErrors: true,
}

const undeclaredNamePrefix = "undeclared name: "

func run(pass *analysis.Pass) (interface{}, error) {
	for _, err := range analysisinternal.GetTypeErrors(pass) {
		if !strings.HasPrefix(err.Msg, undeclaredNamePrefix) {
			continue
		}
		name := strings.TrimPrefix(err.Msg, undeclaredNamePrefix)
		var file *ast.File
		for _, f := range pass.Files {
			if f.Pos() <= err.Pos && err.Pos < f.End() {
				file = f
				break
			}
		}
		if file == nil {
			continue
		}

		// Get the path for the relevant range.
		path, _ := astutil.PathEnclosingInterval(file, err.Pos, err.Pos)
		if len(path) < 2 {
			continue
		}
		ident, ok := path[0].(*ast.Ident)
		if !ok || ident.Name != name {
			continue
		}
		// Skip selector expressions because it might be too complex
		// to try and provide a suggested fix for fields and methods.
		if _, ok := path[1].(*ast.SelectorExpr); ok {
			continue
		}
		// TODO(golang.org/issue/34644): in a follow up handle call expressions
		// with suggested fix to create function
		if _, ok := path[1].(*ast.CallExpr); ok {
			continue
		}
		// Get the enclosing statement.
		enclosingIndex := -1
		for i, p := range path {
			if _, ok := p.(ast.Stmt); ok && enclosingIndex == -1 {
				enclosingIndex = i
				break
			}
		}
		if enclosingIndex == -1 {
			continue
		}

		// Get the place to insert the new statement.
		insertBeforeStmt := stmtToInsertVarBefore(path, enclosingIndex)
		if insertBeforeStmt == nil {
			continue
		}

		var buf bytes.Buffer
		if err := format.Node(&buf, pass.Fset, file); err != nil {
			continue
		}
		old := buf.Bytes()
		insertBefore := pass.Fset.Position(insertBeforeStmt.Pos()).Offset

		// Get the indent to add on the line after the new statement.
		// Since this will have a parse error, we can not use format.Source().
		contentBeforeStmt, indent := old[:insertBefore], "\n"
		if nl := bytes.LastIndex(contentBeforeStmt, []byte("\n")); nl != -1 {
			indent = string(contentBeforeStmt[nl:])
		}
		// Create the new local variable statement.
		newStmt := fmt.Sprintf("%s := %s", ident.Name, indent)

		pass.Report(analysis.Diagnostic{
			Pos:     err.Pos,
			End:     analysisinternal.TypeErrorEndPos(pass.Fset, old, err.Pos),
			Message: err.Msg,
			SuggestedFixes: []analysis.SuggestedFix{{
				Message: fmt.Sprintf("Create variable \"%s\"", ident.Name),
				TextEdits: []analysis.TextEdit{{
					Pos:     insertBeforeStmt.Pos(),
					End:     insertBeforeStmt.Pos(),
					NewText: []byte(newStmt),
				}},
			}},
		})
	}
	return nil, nil
}

// stmtToInsertVarBefore returns the ast.Stmt before which we can safely insert a new variable.
// Some examples:
//
// Basic Example:
// z := 1
// y := z + x
// If x is undeclared, then this function would return `y := z + x`, so that we
// can insert `x := ` on the line before `y := z + x`.
//
// If stmt example:
// if z == 1 {
// } else if z == y {}
// If y is undeclared, then this function would return `if z == 1 {`, because we cannot
// insert a statement between an if and an else if statement. As a result, we need to find
// the top of the if chain to insert `y := ` before.
func stmtToInsertVarBefore(path []ast.Node, enclosingIndex int) ast.Stmt {
	enclosingStmt := path[enclosingIndex]
	switch enclosingStmt.(type) {
	case *ast.IfStmt:
		// The enclosingStmt is inside of the if declaration,
		// We need to check if we are in an else-if stmt and
		// get the base if statement.
		return baseIfStmt(path, enclosingIndex)
	case *ast.CaseClause:
		// Get the enclosing switch stmt if the enclosingStmt is
		// inside of the case statement.
		for i := enclosingIndex + 1; i < len(path); i++ {
			if node, ok := path[i].(*ast.SwitchStmt); ok {
				return node
			} else if node, ok := path[i].(*ast.TypeSwitchStmt); ok {
				return node
			}
		}
	}
	if len(path) <= enclosingIndex+1 {
		return enclosingStmt.(ast.Stmt)
	}
	// Check if the enclosing statement is inside another node.
	switch expr := path[enclosingIndex+1].(type) {
	case *ast.IfStmt:
		// Get the base if statement.
		return baseIfStmt(path, enclosingIndex+1)
	case *ast.ForStmt:
		if expr.Init == enclosingStmt || expr.Post == enclosingStmt {
			return expr
		}
	}
	return enclosingStmt.(ast.Stmt)
}

// baseIfStmt walks up the if/else-if chain until we get to
// the top of the current if chain.
func baseIfStmt(path []ast.Node, index int) ast.Stmt {
	stmt := path[index]
	for i := index + 1; i < len(path); i++ {
		if node, ok := path[i].(*ast.IfStmt); ok && node.Else == stmt {
			stmt = node
			continue
		}
		break
	}
	return stmt.(ast.Stmt)
}
