// 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 hooks

import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"sync"
	"time"

	"github.com/sergi/go-diff/diffmatchpatch"
	"golang.org/x/tools/gopls/internal/bug"
	"golang.org/x/tools/internal/diff"
)

// structure for saving information about diffs
// while the new code is being rolled out
type diffstat struct {
	Before, After      int
	Oldedits, Newedits int
	Oldtime, Newtime   time.Duration
	Stack              string
	Msg                string `json:",omitempty"` // for errors
	Ignored            int    `json:",omitempty"` // numbr of skipped records with 0 edits
}

var (
	ignoredMu sync.Mutex
	ignored   int // counter of diff requests on equal strings

	diffStatsOnce sync.Once
	diffStats     *os.File // never closed
)

// save writes a JSON record of statistics about diff requests to a temporary file.
func (s *diffstat) save() {
	diffStatsOnce.Do(func() {
		f, err := os.CreateTemp("", "gopls-diff-stats-*")
		if err != nil {
			log.Printf("can't create diff stats temp file: %v", err) // e.g. disk full
			return
		}
		diffStats = f
	})
	if diffStats == nil {
		return
	}

	// diff is frequently called with equal strings,
	// so we count repeated instances but only print every 15th.
	ignoredMu.Lock()
	if s.Oldedits == 0 && s.Newedits == 0 {
		ignored++
		if ignored < 15 {
			ignoredMu.Unlock()
			return
		}
	}
	s.Ignored = ignored
	ignored = 0
	ignoredMu.Unlock()

	// Record the name of the file in which diff was called.
	// There aren't many calls, so only the base name is needed.
	if _, file, line, ok := runtime.Caller(2); ok {
		s.Stack = fmt.Sprintf("%s:%d", filepath.Base(file), line)
	}
	x, err := json.Marshal(s)
	if err != nil {
		log.Fatalf("internal error marshalling JSON: %v", err)
	}
	fmt.Fprintf(diffStats, "%s\n", x)
}

// disaster is called when the diff algorithm panics or produces a
// diff that cannot be applied. It saves the broken input in a
// new temporary file and logs the file name, which is returned.
func disaster(before, after string) string {
	// We use the pid to salt the name, not os.TempFile,
	// so that each process creates at most one file.
	// One is sufficient for a bug report.
	filename := fmt.Sprintf("%s/gopls-diff-bug-%x", os.TempDir(), os.Getpid())

	// We use NUL as a separator: it should never appear in Go source.
	data := before + "\x00" + after

	if err := os.WriteFile(filename, []byte(data), 0600); err != nil {
		log.Printf("failed to write diff bug report: %v", err)
		return ""
	}

	bug.Reportf("Bug detected in diff algorithm! Please send file %s to the maintainers of gopls if you are comfortable sharing its contents.", filename)

	return filename
}

// BothDiffs edits calls both the new and old diffs, checks that the new diffs
// change before into after, and attempts to preserve some statistics.
func BothDiffs(before, after string) (edits []diff.Edit) {
	// The new diff code contains a lot of internal checks that panic when they
	// fail. This code catches the panics, or other failures, tries to save
	// the failing example (and it would ask the user to send it back to us, and
	// changes options.newDiff to 'old', if only we could figure out how.)
	stat := diffstat{Before: len(before), After: len(after)}
	now := time.Now()
	oldedits := ComputeEdits(before, after)
	stat.Oldedits = len(oldedits)
	stat.Oldtime = time.Since(now)
	defer func() {
		if r := recover(); r != nil {
			disaster(before, after)
			edits = oldedits
		}
	}()
	now = time.Now()
	newedits := diff.Strings(before, after)
	stat.Newedits = len(newedits)
	stat.Newtime = time.Now().Sub(now)
	got, err := diff.Apply(before, newedits)
	if err != nil || got != after {
		stat.Msg += "FAIL"
		disaster(before, after)
		stat.save()
		return oldedits
	}
	stat.save()
	return newedits
}

// ComputeEdits computes a diff using the github.com/sergi/go-diff implementation.
func ComputeEdits(before, after string) (edits []diff.Edit) {
	// The go-diff library has an unresolved panic (see golang/go#278774).
	// TODO(rstambler): Remove the recover once the issue has been fixed
	// upstream.
	defer func() {
		if r := recover(); r != nil {
			bug.Reportf("unable to compute edits: %s", r)
			// Report one big edit for the whole file.
			edits = []diff.Edit{{
				Start: 0,
				End:   len(before),
				New:   after,
			}}
		}
	}()
	diffs := diffmatchpatch.New().DiffMain(before, after, true)
	edits = make([]diff.Edit, 0, len(diffs))
	offset := 0
	for _, d := range diffs {
		start := offset
		switch d.Type {
		case diffmatchpatch.DiffDelete:
			offset += len(d.Text)
			edits = append(edits, diff.Edit{Start: start, End: offset})
		case diffmatchpatch.DiffEqual:
			offset += len(d.Text)
		case diffmatchpatch.DiffInsert:
			edits = append(edits, diff.Edit{Start: start, End: start, New: d.Text})
		}
	}
	return edits
}
