// Copyright 2025 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 refactor

// This file defines operations for computing deletion edits.

import (
	"fmt"
	"go/ast"
	"go/token"
	"go/types"
	"slices"

	"golang.org/x/tools/go/ast/edge"
	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/internal/astutil"
	"golang.org/x/tools/internal/typesinternal"
	"golang.org/x/tools/internal/typesinternal/typeindex"
)

// DeleteVar returns edits to delete the declaration of a variable or
// constant whose defining identifier is curId.
//
// It handles variants including:
// - GenDecl > ValueSpec versus AssignStmt;
// - RHS expression has effects, or not;
// - entire statement/declaration may be eliminated;
// and removes associated comments.
//
// If it cannot make the necessary edits, such as for a function
// parameter or result, it returns nil.
func DeleteVar(tokFile *token.File, info *types.Info, curId inspector.Cursor) []Edit {
	switch curId.ParentEdgeKind() {
	case edge.ValueSpec_Names:
		return deleteVarFromValueSpec(tokFile, info, curId)

	case edge.AssignStmt_Lhs:
		return deleteVarFromAssignStmt(tokFile, info, curId)
	}

	// e.g. function receiver, parameter, or result,
	// or "switch v := expr.(T) {}" (which has no object).
	return nil
}

// deleteVarFromValueSpec returns edits to delete the declaration of a
// variable or constant within a ValueSpec.
//
// Precondition: curId is Ident beneath ValueSpec.Names beneath GenDecl.
//
// See also [deleteVarFromAssignStmt], which has parallel structure.
func deleteVarFromValueSpec(tokFile *token.File, info *types.Info, curIdent inspector.Cursor) []Edit {
	var (
		id      = curIdent.Node().(*ast.Ident)
		curSpec = curIdent.Parent()
		spec    = curSpec.Node().(*ast.ValueSpec)
	)

	declaresOtherNames := slices.ContainsFunc(spec.Names, func(name *ast.Ident) bool {
		return name != id && name.Name != "_"
	})
	noRHSEffects := !slices.ContainsFunc(spec.Values, func(rhs ast.Expr) bool {
		return !typesinternal.NoEffects(info, rhs)
	})
	if !declaresOtherNames && noRHSEffects {
		// The spec is no longer needed, either to declare
		// other variables, or for its side effects.
		return DeleteSpec(tokFile, curSpec)
	}

	// The spec is still needed, either for
	// at least one LHS, or for effects on RHS.
	// Blank out or delete just one LHS.

	index := curIdent.ParentEdgeIndex() // index of LHS within ValueSpec.Names

	// If there is no RHS, we can delete the LHS.
	if len(spec.Values) == 0 {
		var pos, end token.Pos
		if index == len(spec.Names)-1 {
			// Delete final name.
			//
			// var _, lhs1 T
			//      ------
			pos = spec.Names[index-1].End()
			end = spec.Names[index].End()
		} else {
			// Delete non-final name.
			//
			// var lhs0, _ T
			//     ------
			pos = spec.Names[index].Pos()
			end = spec.Names[index+1].Pos()
		}
		return []Edit{{
			Pos: pos,
			End: end,
		}}
	}

	// If the assignment is n:n and the RHS has no effects,
	// we can delete the LHS and its corresponding RHS.
	if len(spec.Names) == len(spec.Values) &&
		typesinternal.NoEffects(info, spec.Values[index]) {

		if index == len(spec.Names)-1 {
			// Delete final items.
			//
			// var _, lhs1 = rhs0, rhs1
			//      ------       ------
			return []Edit{
				{
					Pos: spec.Names[index-1].End(),
					End: spec.Names[index].End(),
				},
				{
					Pos: spec.Values[index-1].End(),
					End: spec.Values[index].End(),
				},
			}
		} else {
			// Delete non-final items.
			//
			// var lhs0, _ = rhs0, rhs1
			//     ------    ------
			return []Edit{
				{
					Pos: spec.Names[index].Pos(),
					End: spec.Names[index+1].Pos(),
				},
				{
					Pos: spec.Values[index].Pos(),
					End: spec.Values[index+1].Pos(),
				},
			}
		}
	}

	// We cannot delete the RHS.
	// Blank out the LHS.
	return []Edit{{
		Pos:     id.Pos(),
		End:     id.End(),
		NewText: []byte("_"),
	}}
}

// Precondition: curId is Ident beneath AssignStmt.Lhs.
//
// See also [deleteVarFromValueSpec], which has parallel structure.
func deleteVarFromAssignStmt(tokFile *token.File, info *types.Info, curIdent inspector.Cursor) []Edit {
	var (
		id      = curIdent.Node().(*ast.Ident)
		curStmt = curIdent.Parent()
		assign  = curStmt.Node().(*ast.AssignStmt)
	)

	declaresOtherNames := slices.ContainsFunc(assign.Lhs, func(lhs ast.Expr) bool {
		lhsId, ok := lhs.(*ast.Ident)
		return ok && lhsId != id && lhsId.Name != "_"
	})
	noRHSEffects := !slices.ContainsFunc(assign.Rhs, func(rhs ast.Expr) bool {
		return !typesinternal.NoEffects(info, rhs)
	})
	if !declaresOtherNames && noRHSEffects {
		// The assignment is no longer needed, either to
		// declare other variables, or for its side effects.
		if edits := DeleteStmt(tokFile, curStmt); edits != nil {
			return edits
		}
		// Statement could not not be deleted in this context.
		// Fall back to conservative deletion.
	}

	// The assign is still needed, either for
	// at least one LHS, or for effects on RHS,
	// or because it cannot deleted because of its context.
	// Blank out or delete just one LHS.

	// If the assignment is 1:1 and the RHS has no effects,
	// we can delete the LHS and its corresponding RHS.
	index := curIdent.ParentEdgeIndex()
	if len(assign.Lhs) > 1 &&
		len(assign.Lhs) == len(assign.Rhs) &&
		typesinternal.NoEffects(info, assign.Rhs[index]) {

		if index == len(assign.Lhs)-1 {
			// Delete final items.
			//
			// _, lhs1 := rhs0, rhs1
			//  ------        ------
			return []Edit{
				{
					Pos: assign.Lhs[index-1].End(),
					End: assign.Lhs[index].End(),
				},
				{
					Pos: assign.Rhs[index-1].End(),
					End: assign.Rhs[index].End(),
				},
			}
		} else {
			// Delete non-final items.
			//
			// lhs0, _ := rhs0, rhs1
			// ------     ------
			return []Edit{
				{
					Pos: assign.Lhs[index].Pos(),
					End: assign.Lhs[index+1].Pos(),
				},
				{
					Pos: assign.Rhs[index].Pos(),
					End: assign.Rhs[index+1].Pos(),
				},
			}
		}
	}

	// We cannot delete the RHS.
	// Blank out the LHS.
	edits := []Edit{{
		Pos:     id.Pos(),
		End:     id.End(),
		NewText: []byte("_"),
	}}

	// If this eliminates the final variable declared by
	// an := statement, we need to turn it into an =
	// assignment to avoid a "no new variables on left
	// side of :=" error.
	if !declaresOtherNames {
		edits = append(edits, Edit{
			Pos:     assign.TokPos,
			End:     assign.TokPos + token.Pos(len(":=")),
			NewText: []byte("="),
		})
	}

	return edits
}

// DeleteSpec returns edits to delete the {Type,Value}Spec identified by curSpec.
//
// TODO(adonovan): add test suite. Test for consts as well.
func DeleteSpec(tokFile *token.File, curSpec inspector.Cursor) []Edit {
	var (
		spec    = curSpec.Node().(ast.Spec)
		curDecl = curSpec.Parent()
		decl    = curDecl.Node().(*ast.GenDecl)
	)

	// If it is the sole spec in the decl,
	// delete the entire decl.
	if len(decl.Specs) == 1 {
		return DeleteDecl(tokFile, curDecl)
	}

	// Delete the spec and its comments.
	index := curSpec.ParentEdgeIndex() // index of ValueSpec within GenDecl.Specs
	pos, end := spec.Pos(), spec.End()
	if doc := astutil.DocComment(spec); doc != nil {
		pos = doc.Pos() // leading comment
	}
	if index == len(decl.Specs)-1 {
		// Delete final spec.
		if c := eolComment(spec); c != nil {
			//  var (v int // comment \n)
			end = c.End()
		}
	} else {
		// Delete non-final spec.
		//   var ( a T; b T )
		//         -----
		end = decl.Specs[index+1].Pos()
	}
	return []Edit{{
		Pos: pos,
		End: end,
	}}
}

// DeleteDecl returns edits to delete the ast.Decl identified by curDecl.
//
// TODO(adonovan): add test suite.
func DeleteDecl(tokFile *token.File, curDecl inspector.Cursor) []Edit {
	decl := curDecl.Node().(ast.Decl)

	ek := curDecl.ParentEdgeKind()
	switch ek {
	case edge.DeclStmt_Decl:
		return DeleteStmt(tokFile, curDecl.Parent())

	case edge.File_Decls:
		pos, end := decl.Pos(), decl.End()
		if doc := astutil.DocComment(decl); doc != nil {
			pos = doc.Pos()
		}

		// Delete free-floating comments on same line as rparen.
		//    var (...) // comment
		var (
			file        = curDecl.Parent().Node().(*ast.File)
			lineOf      = tokFile.Line
			declEndLine = lineOf(decl.End())
		)
		for _, cg := range file.Comments {
			for _, c := range cg.List {
				if c.Pos() < end {
					continue // too early
				}
				commentEndLine := lineOf(c.End())
				if commentEndLine > declEndLine {
					break // too late
				} else if lineOf(c.Pos()) == declEndLine && commentEndLine == declEndLine {
					end = c.End()
				}
			}
		}

		return []Edit{{
			Pos: pos,
			End: end,
		}}

	default:
		panic(fmt.Sprintf("Decl parent is %v, want DeclStmt or File", ek))
	}
}

// find leftmost Pos bigger than start and rightmost less than end
func filterPos(nds []*ast.Comment, start, end token.Pos) (token.Pos, token.Pos, bool) {
	l, r := end, token.NoPos
	ok := false
	for _, n := range nds {
		if n.Pos() > start && n.Pos() < l {
			l = n.Pos()
			ok = true
		}
		if n.End() <= end && n.End() > r {
			r = n.End()
			ok = true
		}
	}
	return l, r, ok
}

// DeleteStmt returns the edits to remove the [ast.Stmt] identified by
// curStmt if it recognizes the context. It returns nil otherwise.
// TODO(pjw, adonovan): it should not return nil, it should return an error
//
// DeleteStmt is called with just the AST so it has trouble deciding if
// a comment is associated with the statement to be deleted. For instance,
//
//	for /*A*/ init()/*B*/;/*C/cond()/*D/;/*E*/post() /*F*/ { /*G*/}
//
// comment B and C are indistinguishable, as are D and E. That is, as the
// AST does not say where the semicolons are, B and C could go either
// with the init() or the cond(), so cannot be removed safely. The same
// is true for D, E, and the post(). (And there are other similar cases.)
// But the other comments can be removed as they are unambiguously
// associated with the statement being deleted. In particular,
// it removes whole lines like
//
//	stmt // comment
func DeleteStmt(file *token.File, curStmt inspector.Cursor) []Edit {
	// if the stmt is on a line by itself, or a range of lines, delete the whole thing
	// including comments. Except for the heads of switches, type
	// switches, and for-statements that's the usual case. Complexity occurs where
	// there are multiple statements on the same line, and adjacent comments.

	// In that case we remove some adjacent comments:
	// In me()/*A*/;b(), comment A cannot be removed, because the ast
	// is indistinguishable from me();/*A*/b()
	// and the same for cases like switch me()/*A*/; x.(type) {

	// this would be more precise with the file contents, or if the ast
	// contained the location of semicolons
	var (
		stmt          = curStmt.Node().(ast.Stmt)
		tokFile       = file
		lineOf        = tokFile.Line
		stmtStartLine = lineOf(stmt.Pos())
		stmtEndLine   = lineOf(stmt.End())

		leftSyntax, rightSyntax     token.Pos      // pieces of parent node on stmt{Start,End}Line
		leftComments, rightComments []*ast.Comment // comments before/after stmt on the same line
	)

	// remember the Pos that are on the same line as stmt
	use := func(left, right token.Pos) {
		if lineOf(left) == stmtStartLine {
			leftSyntax = left
		}
		if lineOf(right) == stmtEndLine {
			rightSyntax = right
		}
	}

	// find the comments, if any, on the same line
Big:
	for _, cg := range astutil.EnclosingFile(curStmt).Comments {
		for _, co := range cg.List {
			if lineOf(co.End()) < stmtStartLine {
				continue
			} else if lineOf(co.Pos()) > stmtEndLine {
				break Big // no more are possible
			}
			if lineOf(co.End()) == stmtStartLine && co.End() <= stmt.Pos() {
				// comment is before the statement
				leftComments = append(leftComments, co)
			} else if lineOf(co.Pos()) == stmtEndLine && co.Pos() >= stmt.End() {
				// comment is after the statement
				rightComments = append(rightComments, co)
			}
		}
	}

	// find any other syntax on the same line
	var (
		leftStmt, rightStmt token.Pos // end/start positions of sibling statements in a []Stmt list
		inStmtList          = false
		curParent           = curStmt.Parent()
	)
	switch parent := curParent.Node().(type) {
	case *ast.BlockStmt:
		use(parent.Lbrace, parent.Rbrace)
		inStmtList = true
	case *ast.CaseClause:
		use(parent.Colon, curStmt.Parent().Parent().Node().(*ast.BlockStmt).Rbrace)
		inStmtList = true
	case *ast.CommClause:
		if parent.Comm == stmt {
			return nil // maybe the user meant to remove the entire CommClause?
		}
		use(parent.Colon, curStmt.Parent().Parent().Node().(*ast.BlockStmt).Rbrace)
		inStmtList = true
	case *ast.ForStmt:
		use(parent.For, parent.Body.Lbrace)
		// special handling, as init;cond;post BlockStmt is not a statement list
		if parent.Init != nil && parent.Cond != nil && stmt == parent.Init && lineOf(parent.Cond.Pos()) == lineOf(stmt.End()) {
			rightStmt = parent.Cond.Pos()
		} else if parent.Post != nil && parent.Cond != nil && stmt == parent.Post && lineOf(parent.Cond.End()) == lineOf(stmt.Pos()) {
			leftStmt = parent.Cond.End()
		}
	case *ast.IfStmt:
		switch stmt {
		case parent.Init:
			use(parent.If, parent.Body.Lbrace)
		case parent.Else:
			// stmt is the {...} in "if cond {} else {...}" and removing
			// it would require removing the 'else' keyword, but the ast
			// does not contain its position.
			return nil
		}
	case *ast.SwitchStmt:
		use(parent.Switch, parent.Body.Lbrace)
	case *ast.TypeSwitchStmt:
		if stmt == parent.Assign {
			return nil // don't remove .(type)
		}
		use(parent.Switch, parent.Body.Lbrace)
	default:
		return nil // not one of ours
	}

	if inStmtList {
		// find the siblings, if any, on the same line
		if prev, found := curStmt.PrevSibling(); found && lineOf(prev.Node().End()) == stmtStartLine {
			if _, ok := prev.Node().(ast.Stmt); ok {
				leftStmt = prev.Node().End() // preceding statement ends on same line
			}
		}
		if next, found := curStmt.NextSibling(); found && lineOf(next.Node().Pos()) == stmtEndLine {
			rightStmt = next.Node().Pos() // following statement begins on same line
		}
	}

	// compute the left and right limits of the edit
	var leftEdit, rightEdit token.Pos
	if leftStmt.IsValid() {
		leftEdit = stmt.Pos() // can't remove preceding comments: a()/*A*/; me()
	} else if leftSyntax.IsValid() {
		// remove intervening leftComments
		if a, _, ok := filterPos(leftComments, leftSyntax, stmt.Pos()); ok {
			leftEdit = a
		} else {
			leftEdit = stmt.Pos()
		}
	} else { // remove whole line
		for leftEdit = stmt.Pos(); lineOf(leftEdit) == stmtStartLine; leftEdit-- {
		}
		if leftEdit < stmt.Pos() {
			leftEdit++ // beginning of line
		}
	}
	if rightStmt.IsValid() {
		rightEdit = stmt.End() // can't remove following comments
	} else if rightSyntax.IsValid() {
		// remove intervening rightComments
		if _, b, ok := filterPos(rightComments, stmt.End(), rightSyntax); ok {
			rightEdit = b
		} else {
			rightEdit = stmt.End()
		}
	} else { // remove whole line
		fend := token.Pos(file.Base()) + token.Pos(file.Size())
		for rightEdit = stmt.End(); fend >= rightEdit && lineOf(rightEdit) == stmtEndLine; rightEdit++ {
		}
		// don't remove \n if there was other stuff earlier
		if leftSyntax.IsValid() || leftStmt.IsValid() {
			rightEdit--
		}
	}

	return []Edit{{Pos: leftEdit, End: rightEdit}}
}

// DeleteUnusedVars computes the edits required to delete the
// declarations of any local variables whose last uses are in the
// curDelend subtree, which is about to be deleted.
func DeleteUnusedVars(index *typeindex.Index, info *types.Info, tokFile *token.File, curDelend inspector.Cursor) []Edit {
	// TODO(adonovan): we might want to generalize this by
	// splitting the two phases below, so that we can gather
	// across a whole sequence of deletions then finally compute the
	// set of variables that are no longer wanted.

	// Count number of deletions of each var.
	delcount := make(map[*types.Var]int)
	for curId := range curDelend.Preorder((*ast.Ident)(nil)) {
		id := curId.Node().(*ast.Ident)
		if v, ok := info.Uses[id].(*types.Var); ok &&
			typesinternal.GetVarKind(v) == typesinternal.LocalVar { // always false before go1.25
			delcount[v]++
		}
	}

	// Delete declaration of each var that became unused.
	var edits []Edit
	for v, count := range delcount {
		if len(slices.Collect(index.Uses(v))) == count {
			if curDefId, ok := index.Def(v); ok {
				edits = append(edits, DeleteVar(tokFile, info, curDefId)...)
			}
		}
	}
	return edits
}

func eolComment(n ast.Node) *ast.CommentGroup {
	// TODO(adonovan): support:
	//    func f() {...} // comment
	switch n := n.(type) {
	case *ast.GenDecl:
		if !n.TokPos.IsValid() && len(n.Specs) == 1 {
			return eolComment(n.Specs[0])
		}
	case *ast.ValueSpec:
		return n.Comment
	case *ast.TypeSpec:
		return n.Comment
	}
	return nil
}
