// 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 (
	"bytes"
	"flag"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"text/scanner"
)

var update = flag.Bool("update", false, "update .golden files")

// gofmtFlags looks for a comment of the form
//
//	//gofmt flags
//
// within the first maxLines lines of the given file,
// and returns the flags string, if any. Otherwise it
// returns the empty string.
func gofmtFlags(filename string, maxLines int) string {
	f, err := os.Open(filename)
	if err != nil {
		return "" // ignore errors - they will be found later
	}
	defer f.Close()

	// initialize scanner
	var s scanner.Scanner
	s.Init(f)
	s.Error = func(*scanner.Scanner, string) {}       // ignore errors
	s.Mode = scanner.GoTokens &^ scanner.SkipComments // want comments

	// look for //gofmt comment
	for s.Line <= maxLines {
		switch s.Scan() {
		case scanner.Comment:
			const prefix = "//gofmt "
			if t := s.TokenText(); strings.HasPrefix(t, prefix) {
				return strings.TrimSpace(t[len(prefix):])
			}
		case scanner.EOF:
			return ""
		}

	}

	return ""
}

func runTest(t *testing.T, in, out string) {
	// process flags
	*simplifyAST = false
	*rewriteRule = ""
	stdin := false
	for _, flag := range strings.Split(gofmtFlags(in, 20), " ") {
		elts := strings.SplitN(flag, "=", 2)
		name := elts[0]
		value := ""
		if len(elts) == 2 {
			value = elts[1]
		}
		switch name {
		case "":
			// no flags
		case "-r":
			*rewriteRule = value
		case "-s":
			*simplifyAST = true
		case "-stdin":
			// fake flag - pretend input is from stdin
			stdin = true
		case "-G":
			*allowTypeParams = true
		default:
			t.Errorf("unrecognized flag name: %s", name)
		}
	}

	initParserMode()
	initRewrite()

	var buf bytes.Buffer
	err := processFile(in, nil, &buf, stdin)
	if err != nil {
		t.Error(err)
		return
	}

	expected, err := os.ReadFile(out)
	if err != nil {
		t.Error(err)
		return
	}

	if got := buf.Bytes(); !bytes.Equal(got, expected) {
		if *update {
			if in != out {
				if err := os.WriteFile(out, got, 0666); err != nil {
					t.Error(err)
				}
				return
			}
			// in == out: don't accidentally destroy input
			t.Errorf("WARNING: -update did not rewrite input file %s", in)
		}

		t.Errorf("(gofmt %s) != %s (see %s.gofmt)", in, out, in)
		d, err := diffWithReplaceTempFile(expected, got, in)
		if err == nil {
			t.Errorf("%s", d)
		}
		if err := os.WriteFile(in+".gofmt", got, 0666); err != nil {
			t.Error(err)
		}
	}
}

// TestRewrite processes testdata/*.input files and compares them to the
// corresponding testdata/*.golden files. The gofmt flags used to process
// a file must be provided via a comment of the form
//
//	//gofmt flags
//
// in the processed file within the first 20 lines, if any.
func TestRewrite(t *testing.T) {
	// determine input files
	match, err := filepath.Glob("testdata/*.input")
	if err != nil {
		t.Fatal(err)
	}

	// add larger examples
	match = append(match, "gofmt.go", "gofmt_test.go")

	for _, in := range match {
		out := in // for files where input and output are identical
		if strings.HasSuffix(in, ".input") {
			out = in[:len(in)-len(".input")] + ".golden"
		}
		runTest(t, in, out)
		if in != out {
			// Check idempotence.
			runTest(t, out, out)
		}
	}
}

// Test case for issue 3961.
func TestCRLF(t *testing.T) {
	const input = "testdata/crlf.input"   // must contain CR/LF's
	const golden = "testdata/crlf.golden" // must not contain any CR's

	data, err := os.ReadFile(input)
	if err != nil {
		t.Error(err)
	}
	if !bytes.Contains(data, []byte("\r\n")) {
		t.Errorf("%s contains no CR/LF's", input)
	}

	data, err = os.ReadFile(golden)
	if err != nil {
		t.Error(err)
	}
	if bytes.Contains(data, []byte("\r")) {
		t.Errorf("%s contains CR's", golden)
	}
}

func TestBackupFile(t *testing.T) {
	dir, err := os.MkdirTemp("", "gofmt_test")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)
	name, err := backupFile(filepath.Join(dir, "foo.go"), []byte("  package main"), 0644)
	if err != nil {
		t.Fatal(err)
	}
	t.Logf("Created: %s", name)
}

func TestDiff(t *testing.T) {
	if _, err := exec.LookPath("diff"); err != nil {
		t.Skipf("skip test on %s: diff command is required", runtime.GOOS)
	}
	in := []byte("first\nsecond\n")
	out := []byte("first\nthird\n")
	filename := "difftest.txt"
	b, err := diffWithReplaceTempFile(in, out, filename)
	if err != nil {
		t.Fatal(err)
	}

	if runtime.GOOS == "windows" {
		b = bytes.ReplaceAll(b, []byte{'\r', '\n'}, []byte{'\n'})
	}

	bs := bytes.SplitN(b, []byte{'\n'}, 3)
	line0, line1 := bs[0], bs[1]

	if prefix := "--- difftest.txt.orig"; !bytes.HasPrefix(line0, []byte(prefix)) {
		t.Errorf("diff: first line should start with `%s`\ngot: %s", prefix, line0)
	}

	if prefix := "+++ difftest.txt"; !bytes.HasPrefix(line1, []byte(prefix)) {
		t.Errorf("diff: second line should start with `%s`\ngot: %s", prefix, line1)
	}

	want := `@@ -1,2 +1,2 @@
 first
-second
+third
`

	if got := string(bs[2]); got != want {
		t.Errorf("diff: got:\n%s\nwant:\n%s", got, want)
	}
}

func TestReplaceTempFilename(t *testing.T) {
	diff := []byte(`--- /tmp/tmpfile1	2017-02-08 00:53:26.175105619 +0900
+++ /tmp/tmpfile2	2017-02-08 00:53:38.415151275 +0900
@@ -1,2 +1,2 @@
 first
-second
+third
`)
	want := []byte(`--- path/to/file.go.orig	2017-02-08 00:53:26.175105619 +0900
+++ path/to/file.go	2017-02-08 00:53:38.415151275 +0900
@@ -1,2 +1,2 @@
 first
-second
+third
`)
	// Check path in diff output is always slash regardless of the
	// os.PathSeparator (`/` or `\`).
	sep := string(os.PathSeparator)
	filename := strings.Join([]string{"path", "to", "file.go"}, sep)
	got, err := replaceTempFilename(diff, filename)
	if err != nil {
		t.Fatal(err)
	}
	if !bytes.Equal(got, want) {
		t.Errorf("os.PathSeparator='%s': replacedDiff:\ngot:\n%s\nwant:\n%s", sep, got, want)
	}
}
