// Copyright 2021 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.

// Issue 42580: cmd/cgo: shifting identifier position in ast

package errorstest

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

type ShortPosition struct {
	Line    int
	Column  int
	Visited bool
}

type IdentPositionInfo map[string][]ShortPosition

type Visitor struct {
	identPosInfo IdentPositionInfo
	fset         *token.FileSet
	t            *testing.T
}

func (v *Visitor) Visit(node ast.Node) ast.Visitor {
	if ident, ok := node.(*ast.Ident); ok {
		if expectedPositions, ok := v.identPosInfo[ident.Name]; ok {
			gotMatch := false
			var errorMessage strings.Builder
			for caseIndex, expectedPos := range expectedPositions {
				actualPosition := v.fset.PositionFor(ident.Pos(), true)
				errorOccured := false
				if expectedPos.Line != actualPosition.Line {
					fmt.Fprintf(&errorMessage, "wrong line number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Line, actualPosition.Line)
					errorOccured = true
				}
				if expectedPos.Column != actualPosition.Column {
					fmt.Fprintf(&errorMessage, "wrong column number for ident %s: expected: %d got: %d\n", ident.Name, expectedPos.Column, actualPosition.Column)
					errorOccured = true
				}
				if errorOccured {
					continue
				}
				gotMatch = true
				expectedPositions[caseIndex].Visited = true
			}

			if !gotMatch {
				v.t.Errorf(errorMessage.String())
			}
		}
	}
	return v
}

func TestArgumentsPositions(t *testing.T) {
	testdata, err := filepath.Abs("testdata")
	if err != nil {
		t.Fatal(err)
	}

	tmpPath := t.TempDir()

	dir := filepath.Join(tmpPath, "src", "testpositions")
	if err := os.MkdirAll(dir, 0755); err != nil {
		t.Fatal(err)
	}

	cmd := exec.Command("go", "tool", "cgo",
		"-srcdir", testdata,
		"-objdir", dir,
		"issue42580.go")
	cmd.Stderr = new(bytes.Buffer)

	err = cmd.Run()
	if err != nil {
		t.Fatalf("%s: %v\n%s", cmd, err, cmd.Stderr)
	}
	mainProcessed, err := os.ReadFile(filepath.Join(dir, "issue42580.cgo1.go"))
	if err != nil {
		t.Fatal(err)
	}
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, "", mainProcessed, parser.AllErrors)
	if err != nil {
		fmt.Println(err)
		return
	}

	expectation := IdentPositionInfo{
		"checkedPointer": []ShortPosition{
			ShortPosition{
				Line:   32,
				Column: 56,
			},
		},
		"singleInnerPointerChecked": []ShortPosition{
			ShortPosition{
				Line:   37,
				Column: 91,
			},
		},
		"doublePointerChecked": []ShortPosition{
			ShortPosition{
				Line:   42,
				Column: 91,
			},
		},
	}
	for _, decl := range f.Decls {
		if fdecl, ok := decl.(*ast.FuncDecl); ok {
			ast.Walk(&Visitor{expectation, fset, t}, fdecl.Body)
		}
	}
	for ident, positions := range expectation {
		for _, position := range positions {
			if !position.Visited {
				t.Errorf("Position %d:%d missed for %s ident", position.Line, position.Column, ident)
			}
		}
	}
}
