// 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 (
	"crypto/rand"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"math/big"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"sync"
	"time"
	"unicode"

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

// 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 (
	mu      sync.Mutex // serializes writes and protects ignored
	difffd  io.Writer
	ignored int // lots of the diff calls have 0 diffs
)

var fileonce sync.Once

func (s *diffstat) save() {
	// save log records in a file in os.TempDir().
	// diff is frequently called with identical strings, so
	// these are somewhat compressed out
	fileonce.Do(func() {
		fname := filepath.Join(os.TempDir(), fmt.Sprintf("gopls-diff-%x", os.Getpid()))
		fd, err := os.Create(fname)
		if err != nil {
			// now what?
		}
		difffd = fd
	})

	mu.Lock()
	defer mu.Unlock()
	if s.Oldedits == 0 && s.Newedits == 0 {
		if ignored < 15 {
			// keep track of repeated instances of no diffs
			// but only print every 15th
			ignored++
			return
		}
		s.Ignored = ignored + 1
	} else {
		s.Ignored = ignored
	}
	ignored = 0
	// it would be really nice to see why diff was called
	_, f, l, ok := runtime.Caller(2)
	if ok {
		var fname string
		fname = filepath.Base(f) // diff is only called from a few places
		s.Stack = fmt.Sprintf("%s:%d", fname, l)
	}
	x, err := json.Marshal(s)
	if err != nil {
		log.Print(err) // failure to print statistics should not stop gopls
	}
	fmt.Fprintf(difffd, "%s\n", x)
}

// save encrypted versions of the broken input and return the file name
// (the saved strings will have the same diff behavior as the user's strings)
func disaster(before, after string) string {
	// encrypt before and after for privacy. (randomized monoalphabetic cipher)
	// got will contain the substitution cipher
	// for the runes in before and after
	got := map[rune]rune{}
	for _, r := range before {
		got[r] = ' ' // value doesn't matter
	}
	for _, r := range after {
		got[r] = ' '
	}
	repl := initrepl(len(got))
	i := 0
	for k := range got { // randomized
		got[k] = repl[i]
		i++
	}
	// use got to encrypt before and after
	subst := func(r rune) rune { return got[r] }
	first := strings.Map(subst, before)
	second := strings.Map(subst, after)

	// one failure per session is enough, and more private.
	// this saves the last one.
	fname := fmt.Sprintf("%s/gopls-failed-%x", os.TempDir(), os.Getpid())
	fd, err := os.Create(fname)
	defer fd.Close()
	_, err = fmt.Fprintf(fd, "%s\n%s\n", first, second)
	if err != nil {
		// what do we tell the user?
		return ""
	}
	// ask the user to send us the file, somehow
	return fname
}

func initrepl(n int) []rune {
	repl := make([]rune, 0, n)
	for r := rune(0); len(repl) < n; r++ {
		if unicode.IsLetter(r) || unicode.IsNumber(r) {
			repl = append(repl, r)
		}
	}
	// randomize repl
	rdr := rand.Reader
	lim := big.NewInt(int64(len(repl)))
	for i := 1; i < n; i++ {
		v, _ := rand.Int(rdr, lim)
		k := v.Int64()
		repl[i], repl[k] = repl[k], repl[i]
	}
	return repl
}

// 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(uri span.URI, before, after string) (edits []diff.TextEdit, err error) {
	// 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 ut wiykd 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, oerr := ComputeEdits(uri, before, after)
	if oerr != nil {
		stat.Msg += fmt.Sprintf("old:%v", oerr)
	}
	stat.Oldedits = len(Oldedits)
	stat.Oldtime = time.Since(now)
	defer func() {
		if r := recover(); r != nil {
			disaster(before, after)
			edits, err = Oldedits, oerr
		}
	}()
	now = time.Now()
	Newedits, rerr := diff.NComputeEdits(uri, before, after)
	stat.Newedits = len(Newedits)
	stat.Newtime = time.Now().Sub(now)
	got := diff.ApplyEdits(before, Newedits)
	if got != after {
		stat.Msg += "FAIL"
		disaster(before, after)
		stat.save()
		return Oldedits, oerr
	}
	stat.save()
	return Newedits, rerr
}

func ComputeEdits(uri span.URI, before, after string) (edits []diff.TextEdit, err error) {
	// 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 {
			edits = nil
			err = fmt.Errorf("unable to compute edits for %s: %s", uri.Filename(), r)
		}
	}()
	diffs := diffmatchpatch.New().DiffMain(before, after, true)
	edits = make([]diff.TextEdit, 0, len(diffs))
	offset := 0
	for _, d := range diffs {
		start := span.NewPoint(0, 0, offset)
		switch d.Type {
		case diffmatchpatch.DiffDelete:
			offset += len(d.Text)
			edits = append(edits, diff.TextEdit{Span: span.New(uri, start, span.NewPoint(0, 0, offset))})
		case diffmatchpatch.DiffEqual:
			offset += len(d.Text)
		case diffmatchpatch.DiffInsert:
			edits = append(edits, diff.TextEdit{Span: span.New(uri, start, span.Point{}), NewText: d.Text})
		}
	}
	return edits, nil
}
