// 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 modernize

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

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/inspect"
	"golang.org/x/tools/go/ast/edge"
	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/go/types/typeutil"
	typeindexanalyzer "golang.org/x/tools/internal/analysisinternal/typeindex"
	"golang.org/x/tools/internal/typesinternal/typeindex"
)

// stringsseq offers a fix to replace a call to strings.Split with
// SplitSeq or strings.Fields with FieldsSeq
// when it is the operand of a range loop, either directly:
//
//	for _, line := range strings.Split() {...}
//
// or indirectly, if the variable's sole use is the range statement:
//
//	lines := strings.Split()
//	for _, line := range lines {...}
//
// Variants:
// - bytes.SplitSeq
// - bytes.FieldsSeq
func stringsseq(pass *analysis.Pass) {
	var (
		inspect = pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
		index   = pass.ResultOf[typeindexanalyzer.Analyzer].(*typeindex.Index)
		info    = pass.TypesInfo

		stringsSplit  = index.Object("strings", "Split")
		stringsFields = index.Object("strings", "Fields")
		bytesSplit    = index.Object("bytes", "Split")
		bytesFields   = index.Object("bytes", "Fields")
	)
	if !index.Used(stringsSplit, stringsFields, bytesSplit, bytesFields) {
		return
	}

	for curFile := range filesUsing(inspect, info, "go1.24") {
		for curRange := range curFile.Preorder((*ast.RangeStmt)(nil)) {
			rng := curRange.Node().(*ast.RangeStmt)

			// Reject "for i, line := ..." since SplitSeq is not an iter.Seq2.
			// (We require that i is blank.)
			if id, ok := rng.Key.(*ast.Ident); ok && id.Name != "_" {
				continue
			}

			// Find the call operand of the range statement,
			// whether direct or indirect.
			call, ok := rng.X.(*ast.CallExpr)
			if !ok {
				if id, ok := rng.X.(*ast.Ident); ok {
					if v, ok := info.Uses[id].(*types.Var); ok {
						if ek, idx := curRange.ParentEdge(); ek == edge.BlockStmt_List && idx > 0 {
							curPrev, _ := curRange.PrevSibling()
							if assign, ok := curPrev.Node().(*ast.AssignStmt); ok &&
								assign.Tok == token.DEFINE &&
								len(assign.Lhs) == 1 &&
								len(assign.Rhs) == 1 &&
								info.Defs[assign.Lhs[0].(*ast.Ident)] == v &&
								soleUseIs(index, v, id) {
								// Have:
								//    lines := ...
								//    for _, line := range lines {...}
								// and no other uses of lines.
								call, _ = assign.Rhs[0].(*ast.CallExpr)
							}
						}
					}
				}
			}

			if call != nil {
				var edits []analysis.TextEdit
				if rng.Key != nil {
					// Delete (blank) RangeStmt.Key:
					//  for _, line := -> for line :=
					//  for _, _    := -> for
					//  for _       := -> for
					end := rng.Range
					if rng.Value != nil {
						end = rng.Value.Pos()
					}
					edits = append(edits, analysis.TextEdit{
						Pos: rng.Key.Pos(),
						End: end,
					})
				}

				sel, ok := call.Fun.(*ast.SelectorExpr)
				if !ok {
					continue
				}

				switch obj := typeutil.Callee(info, call); obj {
				case stringsSplit, stringsFields, bytesSplit, bytesFields:
					oldFnName := obj.Name()
					seqFnName := fmt.Sprintf("%sSeq", oldFnName)
					pass.Report(analysis.Diagnostic{
						Pos:      sel.Pos(),
						End:      sel.End(),
						Category: "stringsseq",
						Message:  fmt.Sprintf("Ranging over %s is more efficient", seqFnName),
						SuggestedFixes: []analysis.SuggestedFix{{
							Message: fmt.Sprintf("Replace %s with %s", oldFnName, seqFnName),
							TextEdits: append(edits, analysis.TextEdit{
								Pos:     sel.Sel.Pos(),
								End:     sel.Sel.End(),
								NewText: []byte(seqFnName)}),
						}},
					})
				}
			}
		}
	}
}
