// Copyright 2011 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 main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"internal/diff"
	"internal/testenv"
	"strings"
	"testing"
)

func init() {
	// If cgo is enabled, enforce that cgo commands invoked by cmd/fix
	// do not fail during testing.
	if testenv.HasCGO() && testenv.HasGoBuild() {
		// The reportCgoError hook is global, so we can't set it per-test
		// if we want to be able to run those tests in parallel.
		// Instead, simply set it to panic on error: the goroutine dump
		// from the panic should help us determine which test failed.
		reportCgoError = func(err error) {
			panic(fmt.Sprintf("unexpected cgo error: %v", err))
		}
	}
}

type testCase struct {
	Name    string
	Fn      func(*ast.File) bool
	Version int
	In      string
	Out     string
}

var testCases []testCase

func addTestCases(t []testCase, fn func(*ast.File) bool) {
	// Fill in fn to avoid repetition in definitions.
	if fn != nil {
		for i := range t {
			if t[i].Fn == nil {
				t[i].Fn = fn
			}
		}
	}
	testCases = append(testCases, t...)
}

func fnop(*ast.File) bool { return false }

func parseFixPrint(t *testing.T, fn func(*ast.File) bool, desc, in string, mustBeGofmt bool) (out string, fixed, ok bool) {
	file, err := parser.ParseFile(fset, desc, in, parserMode)
	if err != nil {
		t.Errorf("parsing: %v", err)
		return
	}

	outb, err := gofmtFile(file)
	if err != nil {
		t.Errorf("printing: %v", err)
		return
	}
	if s := string(outb); in != s && mustBeGofmt {
		t.Errorf("not gofmt-formatted.\n--- %s\n%s\n--- %s | gofmt\n%s",
			desc, in, desc, s)
		tdiff(t, "want", in, "have", s)
		return
	}

	if fn == nil {
		for _, fix := range fixes {
			if fix.f(file) {
				fixed = true
			}
		}
	} else {
		fixed = fn(file)
	}

	outb, err = gofmtFile(file)
	if err != nil {
		t.Errorf("printing: %v", err)
		return
	}

	return string(outb), fixed, true
}

func TestRewrite(t *testing.T) {
	for _, tt := range testCases {
		tt := tt
		t.Run(tt.Name, func(t *testing.T) {
			if tt.Version == 0 {
				if testing.Verbose() {
					// Don't run in parallel: cmd/fix sometimes writes directly to stderr,
					// and since -v prints which test is currently running we want that
					// information to accurately correlate with the stderr output.
				} else {
					t.Parallel()
				}
			} else {
				old := goVersion
				goVersion = tt.Version
				defer func() {
					goVersion = old
				}()
			}

			// Apply fix: should get tt.Out.
			out, fixed, ok := parseFixPrint(t, tt.Fn, tt.Name, tt.In, true)
			if !ok {
				return
			}

			// reformat to get printing right
			out, _, ok = parseFixPrint(t, fnop, tt.Name, out, false)
			if !ok {
				return
			}

			if tt.Out == "" {
				tt.Out = tt.In
			}
			if out != tt.Out {
				t.Errorf("incorrect output.\n")
				if !strings.HasPrefix(tt.Name, "testdata/") {
					t.Errorf("--- have\n%s\n--- want\n%s", out, tt.Out)
				}
				tdiff(t, "have", out, "want", tt.Out)
				return
			}

			if changed := out != tt.In; changed != fixed {
				t.Errorf("changed=%v != fixed=%v", changed, fixed)
				return
			}

			// Should not change if run again.
			out2, fixed2, ok := parseFixPrint(t, tt.Fn, tt.Name+" output", out, true)
			if !ok {
				return
			}

			if fixed2 {
				t.Errorf("applied fixes during second round")
				return
			}

			if out2 != out {
				t.Errorf("changed output after second round of fixes.\n--- output after first round\n%s\n--- output after second round\n%s",
					out, out2)
				tdiff(t, "first", out, "second", out2)
			}
		})
	}
}

func tdiff(t *testing.T, aname, a, bname, b string) {
	t.Errorf("%s", diff.Diff(aname, []byte(a), bname, []byte(b)))
}
