// Copyright 2017 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 astutil_test

import (
	"bytes"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"testing"

	"golang.org/x/tools/go/ast/astutil"
)

var rewriteTests = [...]struct {
	name       string
	orig, want string
	pre, post  astutil.ApplyFunc
}{
	{name: "nop", orig: "package p\n", want: "package p\n"},

	{name: "replace",
		orig: `package p

var x int
`,
		want: `package p

var t T
`,
		post: func(c *astutil.Cursor) bool {
			if _, ok := c.Node().(*ast.ValueSpec); ok {
				c.Replace(valspec("t", "T"))
				return false
			}
			return true
		},
	},

	{name: "set doc strings",
		orig: `package p

const z = 0

type T struct{}

var x int
`,
		want: `package p
// a foo is a foo
const z = 0
// a foo is a foo
type T struct{}
// a foo is a foo
var x int
`,
		post: func(c *astutil.Cursor) bool {
			if _, ok := c.Parent().(*ast.GenDecl); ok && c.Name() == "Doc" && c.Node() == nil {
				c.Replace(&ast.CommentGroup{List: []*ast.Comment{{Text: "// a foo is a foo"}}})
			}
			return true
		},
	},

	{name: "insert names",
		orig: `package p

const a = 1
`,
		want: `package p

const a, b, c = 1, 2, 3
`,
		pre: func(c *astutil.Cursor) bool {
			if _, ok := c.Parent().(*ast.ValueSpec); ok {
				switch c.Name() {
				case "Names":
					c.InsertAfter(ast.NewIdent("c"))
					c.InsertAfter(ast.NewIdent("b"))
				case "Values":
					c.InsertAfter(&ast.BasicLit{Kind: token.INT, Value: "3"})
					c.InsertAfter(&ast.BasicLit{Kind: token.INT, Value: "2"})
				}
			}
			return true
		},
	},

	{name: "insert",
		orig: `package p

var (
	x int
	y int
)
`,
		want: `package p

var before1 int
var before2 int

var (
	x int
	y int
)
var after2 int
var after1 int
`,
		pre: func(c *astutil.Cursor) bool {
			if _, ok := c.Node().(*ast.GenDecl); ok {
				c.InsertBefore(vardecl("before1", "int"))
				c.InsertAfter(vardecl("after1", "int"))
				c.InsertAfter(vardecl("after2", "int"))
				c.InsertBefore(vardecl("before2", "int"))
			}
			return true
		},
	},

	{name: "delete",
		orig: `package p

var x int
var y int
var z int
`,
		want: `package p

var y int
var z int
`,
		pre: func(c *astutil.Cursor) bool {
			n := c.Node()
			if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
				c.Delete()
			}
			return true
		},
	},

	{name: "insertafter-delete",
		orig: `package p

var x int
var y int
var z int
`,
		want: `package p

var x1 int

var y int
var z int
`,
		pre: func(c *astutil.Cursor) bool {
			n := c.Node()
			if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
				c.InsertAfter(vardecl("x1", "int"))
				c.Delete()
			}
			return true
		},
	},

	{name: "delete-insertafter",
		orig: `package p

var x int
var y int
var z int
`,
		want: `package p

var y int
var x1 int
var z int
`,
		pre: func(c *astutil.Cursor) bool {
			n := c.Node()
			if d, ok := n.(*ast.GenDecl); ok && d.Specs[0].(*ast.ValueSpec).Names[0].Name == "x" {
				c.Delete()
				// The cursor is now effectively atop the 'var y int' node.
				c.InsertAfter(vardecl("x1", "int"))
			}
			return true
		},
	},
}

func valspec(name, typ string) *ast.ValueSpec {
	return &ast.ValueSpec{Names: []*ast.Ident{ast.NewIdent(name)},
		Type: ast.NewIdent(typ),
	}
}

func vardecl(name, typ string) *ast.GenDecl {
	return &ast.GenDecl{
		Tok:   token.VAR,
		Specs: []ast.Spec{valspec(name, typ)},
	}
}

func TestRewrite(t *testing.T) {
	t.Run("*", func(t *testing.T) {
		for _, test := range rewriteTests {
			test := test
			t.Run(test.name, func(t *testing.T) {
				t.Parallel()
				fset := token.NewFileSet()
				f, err := parser.ParseFile(fset, test.name, test.orig, parser.ParseComments)
				if err != nil {
					t.Fatal(err)
				}
				n := astutil.Apply(f, test.pre, test.post)
				var buf bytes.Buffer
				if err := format.Node(&buf, fset, n); err != nil {
					t.Fatal(err)
				}
				got := buf.String()
				if got != test.want {
					t.Errorf("got:\n\n%s\nwant:\n\n%s\n", got, test.want)
				}
			})
		}
	})
}

var sink ast.Node

func BenchmarkRewrite(b *testing.B) {
	for _, test := range rewriteTests {
		b.Run(test.name, func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				b.StopTimer()
				fset := token.NewFileSet()
				f, err := parser.ParseFile(fset, test.name, test.orig, parser.ParseComments)
				if err != nil {
					b.Fatal(err)
				}
				b.StartTimer()
				sink = astutil.Apply(f, test.pre, test.post)
			}
		})
	}
}
