// Copyright 2019 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 diff_test

import (
	"bytes"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"reflect"
	"strings"
	"testing"
	"unicode/utf8"

	"golang.org/x/tools/internal/diff"
	"golang.org/x/tools/internal/diff/difftest"
	"golang.org/x/tools/internal/testenv"
)

func TestApply(t *testing.T) {
	for _, tc := range difftest.TestCases {
		t.Run(tc.Name, func(t *testing.T) {
			got, err := diff.Apply(tc.In, tc.Edits)
			if err != nil {
				t.Fatalf("Apply(Edits) failed: %v", err)
			}
			if got != tc.Out {
				t.Errorf("Apply(Edits): got %q, want %q", got, tc.Out)
			}
			if tc.LineEdits != nil {
				got, err := diff.Apply(tc.In, tc.LineEdits)
				if err != nil {
					t.Fatalf("Apply(LineEdits) failed: %v", err)
				}
				if got != tc.Out {
					t.Errorf("Apply(LineEdits): got %q, want %q", got, tc.Out)
				}
			}
		})
	}
}

func TestNEdits(t *testing.T) {
	for _, tc := range difftest.TestCases {
		edits := diff.Strings(tc.In, tc.Out)
		got, err := diff.Apply(tc.In, edits)
		if err != nil {
			t.Fatalf("Apply failed: %v", err)
		}
		if got != tc.Out {
			t.Fatalf("%s: got %q wanted %q", tc.Name, got, tc.Out)
		}
		if len(edits) < len(tc.Edits) { // should find subline edits
			t.Errorf("got %v, expected %v for %#v", edits, tc.Edits, tc)
		}
	}
}

func TestNRandom(t *testing.T) {
	rnd := rand.New(rand.NewSource(1))
	for i := range 1000 {
		a := randstr(rnd, "abω", 16)
		b := randstr(rnd, "abωc", 16)
		edits := diff.Strings(a, b)
		got, err := diff.Apply(a, edits)
		if err != nil {
			t.Fatalf("Apply failed: %v", err)
		}
		if got != b {
			t.Fatalf("%d: got %q, wanted %q, starting with %q", i, got, b, a)
		}
	}
}

// $ go test -fuzz=FuzzRoundTrip ./internal/diff
func FuzzRoundTrip(f *testing.F) {
	f.Fuzz(func(t *testing.T, a, b string) {
		if !utf8.ValidString(a) || !utf8.ValidString(b) {
			return // inputs must be text
		}
		edits := diff.Strings(a, b)
		got, err := diff.Apply(a, edits)
		if err != nil {
			t.Fatalf("Apply failed: %v", err)
		}
		if got != b {
			t.Fatalf("applying diff(%q, %q) gives %q; edits=%v", a, b, got, edits)
		}
	})
}

func TestLineEdits(t *testing.T) {
	for _, tc := range difftest.TestCases {
		t.Run(tc.Name, func(t *testing.T) {
			want := tc.LineEdits
			if want == nil {
				want = tc.Edits // already line-aligned
			}
			got, err := diff.LineEdits(tc.In, tc.Edits)
			if err != nil {
				t.Fatalf("LineEdits: %v", err)
			}
			if !reflect.DeepEqual(got, want) {
				t.Errorf("in=<<%s>>\nout=<<%s>>\nraw  edits=%s\nline edits=%s\nwant: %s",
					tc.In, tc.Out, tc.Edits, got, want)
			}
			// make sure that applying the edits gives the expected result
			fixed, err := diff.Apply(tc.In, got)
			if err != nil {
				t.Error(err)
			}
			if fixed != tc.Out {
				t.Errorf("Apply(LineEdits): got %q, want %q", fixed, tc.Out)
			}
		})
	}
}

func TestToUnified(t *testing.T) {
	testenv.NeedsTool(t, "patch")
	for _, tc := range difftest.TestCases {
		t.Run(tc.Name, func(t *testing.T) {
			nedits := diff.Lines(tc.In, tc.Out)
			xunified, err := diff.ToUnified(difftest.FileA, difftest.FileB, tc.In, nedits, diff.DefaultContextLines)
			if err != nil {
				t.Fatal(err)
			}
			if xunified == "" {
				return
			}
			orig := filepath.Join(t.TempDir(), "original")
			err = os.WriteFile(orig, []byte(tc.In), 0644)
			if err != nil {
				t.Fatal(err)
			}
			temp := filepath.Join(t.TempDir(), "patched")
			err = os.WriteFile(temp, []byte(tc.In), 0644)
			if err != nil {
				t.Fatal(err)
			}
			cmd := exec.Command("patch", "-p0", "-u", "-s", "-o", temp, orig)
			cmd.Stdin = strings.NewReader(xunified)
			cmd.Stdout = new(bytes.Buffer)
			cmd.Stderr = new(bytes.Buffer)
			if err = cmd.Run(); err != nil {
				t.Fatalf("%v: %q (%q) (%q)", err, cmd.String(),
					cmd.Stderr, cmd.Stdout)
			}
			got, err := os.ReadFile(temp)
			if err != nil {
				t.Fatal(err)
			}
			if string(got) != tc.Out {
				t.Errorf("applying unified failed: got\n%q, wanted\n%q unified\n%q",
					got, tc.Out, xunified)
			}

		})
	}
}

func TestRegressionOld001(t *testing.T) {
	a := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"golang.org/x/tools/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n"

	b := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/safehtml/template\"\n\t\"golang.org/x/tools/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n"
	diffs := diff.Strings(a, b)
	got, err := diff.Apply(a, diffs)
	if err != nil {
		t.Fatalf("Apply failed: %v", err)
	}
	if got != b {
		i := 0
		for ; i < len(a) && i < len(b) && got[i] == b[i]; i++ {
		}
		t.Errorf("oops %vd\n%q\n%q", diffs, got, b)
		t.Errorf("\n%q\n%q", got[i:], b[i:])
	}
}

func TestRegressionOld002(t *testing.T) {
	a := "n\"\n)\n"
	b := "n\"\n\t\"golang.org/x//nnal/stack\"\n)\n"
	diffs := diff.Strings(a, b)
	got, err := diff.Apply(a, diffs)
	if err != nil {
		t.Fatalf("Apply failed: %v", err)
	}
	if got != b {
		i := 0
		for ; i < len(a) && i < len(b) && got[i] == b[i]; i++ {
		}
		t.Errorf("oops %vd\n%q\n%q", diffs, got, b)
		t.Errorf("\n%q\n%q", got[i:], b[i:])
	}
}

// return a random string of length n made of characters from s
func randstr(rnd *rand.Rand, s string, n int) string {
	src := []rune(s)
	x := make([]rune, n)
	for i := range n {
		x[i] = src[rnd.Intn(len(src))]
	}
	return string(x)
}
