// 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 (
	"fmt"
	"math/rand"
	"strings"
	"testing"

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

func TestApplyEdits(t *testing.T) {
	for _, tc := range difftest.TestCases {
		t.Run(tc.Name, func(t *testing.T) {
			t.Helper()
			if got := diff.ApplyEdits(tc.In, tc.Edits); got != tc.Out {
				t.Errorf("ApplyEdits edits got %q, want %q", got, tc.Out)
			}
			if tc.LineEdits != nil {
				if got := diff.ApplyEdits(tc.In, tc.LineEdits); got != tc.Out {
					t.Errorf("ApplyEdits lineEdits got %q, want %q", got, tc.Out)
				}
			}
		})
	}
}

func TestNEdits(t *testing.T) {
	for i, tc := range difftest.TestCases {
		sp := fmt.Sprintf("file://%s.%d", tc.Name, i)
		edits, err := diff.NComputeEdits(span.URI(sp), tc.In, tc.Out)
		if err != nil {
			t.Fatal(err)
		}
		got := diff.ApplyEdits(tc.In, edits)
		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) {
	rand.Seed(1)
	for i := 0; i < 1000; i++ {
		fname := fmt.Sprintf("file://%x", i)
		a := randstr("abω", 16)
		b := randstr("abωc", 16)
		edits, err := diff.NComputeEdits(span.URI(fname), a, b)
		if err != nil {
			t.Fatalf("%q,%q %v", a, b, err)
		}
		got := diff.ApplyEdits(a, edits)
		if got != b {
			t.Fatalf("%d: got %q, wanted %q, starting with %q", i, got, b, a)
		}
	}
}

func TestNLinesRandom(t *testing.T) {
	rand.Seed(2)
	for i := 0; i < 1000; i++ {
		fname := fmt.Sprintf("file://%x", i)
		x := randlines("abω", 4) // avg line length is 6, want a change every 3rd line or so
		v := []rune(x)
		for i := 0; i < len(v); i++ {
			if rand.Float64() < .05 {
				v[i] = 'N'
			}
		}
		y := string(v)
		// occasionally remove the trailing \n
		if rand.Float64() < .1 {
			x = x[:len(x)-1]
		}
		if rand.Float64() < .1 {
			y = y[:len(y)-1]
		}
		a, b := strings.SplitAfter(x, "\n"), strings.SplitAfter(y, "\n")
		edits, err := diff.NComputeLineEdits(span.URI(fname), a, b)
		if err != nil {
			t.Fatalf("%q,%q %v", a, b, err)
		}
		got := diff.ApplyEdits(x, edits)
		if got != y {
			t.Fatalf("%d: got\n%q, wanted\n%q, starting with %q", i, got, y, a)
		}
	}
}

func TestLineEdits(t *testing.T) {
	for _, tc := range difftest.TestCases {
		t.Run(tc.Name, func(t *testing.T) {
			t.Helper()
			// if line edits not specified, it is the same as edits
			edits := tc.LineEdits
			if edits == nil {
				edits = tc.Edits
			}
			if got := diff.LineEdits(tc.In, tc.Edits); diffEdits(got, edits) {
				t.Errorf("LineEdits got %q, want %q", got, edits)
			}
		})
	}
}

func TestUnified(t *testing.T) {
	for _, tc := range difftest.TestCases {
		t.Run(tc.Name, func(t *testing.T) {
			t.Helper()
			unified := fmt.Sprint(diff.ToUnified(difftest.FileA, difftest.FileB, tc.In, tc.Edits))
			if unified != tc.Unified {
				t.Errorf("edits got diff:\n%v\nexpected:\n%v", unified, tc.Unified)
			}
			if tc.LineEdits != nil {
				unified := fmt.Sprint(diff.ToUnified(difftest.FileA, difftest.FileB, tc.In, tc.LineEdits))
				if unified != tc.Unified {
					t.Errorf("lineEdits got diff:\n%v\nexpected:\n%v", unified, tc.Unified)
				}
			}
		})
	}
}

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/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/internal/span\"\n)\n"
	diffs, err := diff.NComputeEdits(span.URI("file://one"), a, b)
	if err != nil {
		t.Error(err)
	}
	got := diff.ApplyEdits(a, diffs)
	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, err := diff.NComputeEdits(span.URI("file://two"), a, b)
	if err != nil {
		t.Error(err)
	}
	got := diff.ApplyEdits(a, diffs)
	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 diffEdits(got, want []diff.TextEdit) bool {
	if len(got) != len(want) {
		return true
	}
	for i, w := range want {
		g := got[i]
		if span.Compare(w.Span, g.Span) != 0 {
			return true
		}
		if w.NewText != g.NewText {
			return true
		}
	}
	return false
}

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

// return some random lines, all ending with \n
func randlines(s string, n int) string {
	src := []rune(s)
	var b strings.Builder
	for i := 0; i < n; i++ {
		for j := 0; j < 4+rand.Intn(4); j++ {
			b.WriteRune(src[rand.Intn(len(src))])
		}
		b.WriteByte('\n')
	}
	return b.String()
}
