package ast

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
)

// ExtractFuncSourceByPosition 根据文件路径与行号，提取包含该行的整个方法源码
// 返回：方法名、完整源码、起止行号
func ExtractFuncSourceByPosition(filePath string, line int) (name string, source string, startLine int, endLine int, err error) {
	// 读取源文件
	src, readErr := os.ReadFile(filePath)
	if readErr != nil {
		err = fmt.Errorf("read file failed: %w", readErr)
		return
	}

	// 解析 AST
	fset := token.NewFileSet()
	file, parseErr := parser.ParseFile(fset, filePath, src, parser.ParseComments)
	if parseErr != nil {
		err = fmt.Errorf("parse file failed: %w", parseErr)
		return
	}

	// 在 AST 中定位包含指定行号的函数声明
	var target *ast.FuncDecl
	ast.Inspect(file, func(n ast.Node) bool {
		fd, ok := n.(*ast.FuncDecl)
		if !ok {
			return true
		}
		s := fset.Position(fd.Pos()).Line
		e := fset.Position(fd.End()).Line
		if line >= s && line <= e {
			target = fd
			startLine = s
			endLine = e
			return false
		}
		return true
	})

	if target == nil {
		err = fmt.Errorf("no function encloses line %d in %s", line, filePath)
		return
	}

	// 使用字节偏移精确提取源码片段（包含注释与原始格式）
	start := fset.Position(target.Pos()).Offset
	end := fset.Position(target.End()).Offset
	if start < 0 || end > len(src) || start >= end {
		err = fmt.Errorf("invalid offsets for function: start=%d end=%d len=%d", start, end, len(src))
		return
	}
	source = string(src[start:end])
	name = target.Name.Name
	return
}
