// Copyright 2022 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 base

import (
	"bytes"
	"cmd/internal/notsha256"
	"cmd/internal/obj"
	"cmd/internal/src"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
)

type writeSyncer interface {
	io.Writer
	Sync() error
}

type hashAndMask struct {
	// a hash h matches if (h^hash)&mask == 0
	hash uint64
	mask uint64
	name string // base name, or base name + "0", "1", etc.
}

type HashDebug struct {
	mu   sync.Mutex // for logfile, posTmp, bytesTmp
	name string     // base name of the flag/variable.
	// what file (if any) receives the yes/no logging?
	// default is os.Stdout
	logfile          writeSyncer
	posTmp           []src.Pos
	bytesTmp         bytes.Buffer
	matches          []hashAndMask // A hash matches if one of these matches.
	yes, no          bool
	fileSuffixOnly   bool // for Pos hashes, remove the directory prefix.
	inlineSuffixOnly bool // for Pos hashes, remove all but the most inline position.
}

// SetFileSuffixOnly controls whether hashing and reporting use the entire
// file path name, just the basename.  This makes hashing more consistent,
// at the expense of being able to certainly locate the file.
func (d *HashDebug) SetFileSuffixOnly(b bool) *HashDebug {
	d.fileSuffixOnly = b
	return d
}

// SetInlineSuffixOnly controls whether hashing and reporting use the entire
// inline position, or just the most-inline suffix.  Compiler debugging tends
// to want the whole inlining, debugging user problems (loopvarhash, e.g.)
// typically does not need to see the entire inline tree, there is just one
// copy of the source code.
func (d *HashDebug) SetInlineSuffixOnly(b bool) *HashDebug {
	d.inlineSuffixOnly = b
	return d
}

// The default compiler-debugging HashDebug, for "-d=gossahash=..."
var hashDebug *HashDebug

var FmaHash *HashDebug     // for debugging fused-multiply-add floating point changes
var LoopVarHash *HashDebug // for debugging shared/private loop variable changes

// DebugHashMatch reports whether debug variable Gossahash
//
//  1. is empty (returns true; this is a special more-quickly implemented case of 4 below)
//
//  2. is "y" or "Y" (returns true)
//
//  3. is "n" or "N" (returns false)
//
//  4. is a suffix of the sha1 hash of pkgAndName (returns true)
//
//  5. OR
//     if the value is in the regular language "[01]+(/[01]+)+"
//     test the [01]+ substrings after in order returning true
//     for the first one that suffix-matches. The substrings AFTER
//     the first slash are numbered 0,1, etc and are named
//     fmt.Sprintf("%s%d", varname, number)
//     Clause 5 is not really intended for human use and only
//     matters for failures that require multiple triggers.
//
// Otherwise it returns false.
//
// Unless Flags.Gossahash is empty, when DebugHashMatch returns true the message
//
//	"%s triggered %s\n", varname, pkgAndName
//
// is printed on the file named in environment variable GSHS_LOGFILE,
// or standard out if that is empty.  "Varname" is either the name of
// the variable or the name of the substring, depending on which matched.
//
// Typical use:
//
//  1. you make a change to the compiler, say, adding a new phase
//
//  2. it is broken in some mystifying way, for example, make.bash builds a broken
//     compiler that almost works, but crashes compiling a test in run.bash.
//
//  3. add this guard to the code, which by default leaves it broken, but does not
//     run the broken new code if Flags.Gossahash is non-empty and non-matching:
//
//     if !base.DebugHashMatch(ir.PkgFuncName(fn)) {
//     return nil // early exit, do nothing
//     }
//
//  4. rebuild w/o the bad code,
//     GOCOMPILEDEBUG=gossahash=n ./all.bash
//     to verify that you put the guard in the right place with the right sense of the test.
//
//  5. use github.com/dr2chase/gossahash to search for the error:
//
//     go install github.com/dr2chase/gossahash@latest
//
//     gossahash -- <the thing that fails>
//
//     for example: GOMAXPROCS=1 gossahash -- ./all.bash
//
//  6. gossahash should return a single function whose miscompilation
//     causes the problem, and you can focus on that.
func DebugHashMatch(pkgAndName string) bool {
	return hashDebug.DebugHashMatch(pkgAndName)
}

// HasDebugHash returns true if Flags.Gossahash is non-empty, which
// results in hashDebug being not-nil.  I.e., if !HasDebugHash(),
// there is no need to create the string for hashing and testing.
func HasDebugHash() bool {
	return hashDebug != nil
}

func toHashAndMask(s, varname string) hashAndMask {
	l := len(s)
	if l > 64 {
		s = s[l-64:]
		l = 64
	}
	m := ^(^uint64(0) << l)
	h, err := strconv.ParseUint(s, 2, 64)
	if err != nil {
		Fatalf("Could not parse %s (=%s) as a binary number", varname, s)
	}

	return hashAndMask{name: varname, hash: h, mask: m}
}

// NewHashDebug returns a new hash-debug tester for the
// environment variable ev.  If ev is not set, it returns
// nil, allowing a lightweight check for normal-case behavior.
func NewHashDebug(ev, s string, file writeSyncer) *HashDebug {
	if s == "" {
		return nil
	}

	hd := &HashDebug{name: ev, logfile: file}
	switch s[0] {
	case 'y', 'Y':
		hd.yes = true
		return hd
	case 'n', 'N':
		hd.no = true
		return hd
	}
	ss := strings.Split(s, "/")
	hd.matches = append(hd.matches, toHashAndMask(ss[0], ev))
	// hash searches may use additional EVs with 0, 1, 2, ... suffixes.
	for i := 1; i < len(ss); i++ {
		evi := fmt.Sprintf("%s%d", ev, i-1) // convention is extras begin indexing at zero
		hd.matches = append(hd.matches, toHashAndMask(ss[i], evi))
	}
	return hd

}

func hashOf(pkgAndName string, param uint64) uint64 {
	return hashOfBytes([]byte(pkgAndName), param)
}

func hashOfBytes(sbytes []byte, param uint64) uint64 {
	hbytes := notsha256.Sum256(sbytes)
	hash := uint64(hbytes[7])<<56 + uint64(hbytes[6])<<48 +
		uint64(hbytes[5])<<40 + uint64(hbytes[4])<<32 +
		uint64(hbytes[3])<<24 + uint64(hbytes[2])<<16 +
		uint64(hbytes[1])<<8 + uint64(hbytes[0])

	if param != 0 {
		// Because param is probably a line number, probably near zero,
		// hash it up a little bit, but even so only the lower-order bits
		// likely matter because search focuses on those.
		p0 := param + uint64(hbytes[9]) + uint64(hbytes[10])<<8 +
			uint64(hbytes[11])<<16 + uint64(hbytes[12])<<24

		p1 := param + uint64(hbytes[13]) + uint64(hbytes[14])<<8 +
			uint64(hbytes[15])<<16 + uint64(hbytes[16])<<24

		param += p0 * p1
		param ^= param>>17 ^ param<<47
	}

	return hash ^ param
}

// DebugHashMatch returns true if either the variable used to create d is
// unset, or if its value is y, or if it is a suffix of the base-two
// representation of the hash of pkgAndName.  If the variable is not nil,
// then a true result is accompanied by stylized output to d.logfile, which
// is used for automated bug search.
func (d *HashDebug) DebugHashMatch(pkgAndName string) bool {
	return d.DebugHashMatchParam(pkgAndName, 0)
}

// DebugHashMatchParam returns true if either the variable used to create d is
// unset, or if its value is y, or if it is a suffix of the base-two
// representation of the hash of pkgAndName and param. If the variable is not
// nil, then a true result is accompanied by stylized output to d.logfile,
// which is used for automated bug search.
func (d *HashDebug) DebugHashMatchParam(pkgAndName string, param uint64) bool {
	if d == nil {
		return true
	}
	if d.no {
		return false
	}

	if d.yes {
		d.logDebugHashMatch(d.name, pkgAndName, "y", param)
		return true
	}

	hash := hashOf(pkgAndName, param)

	for _, m := range d.matches {
		if (m.hash^hash)&m.mask == 0 {
			hstr := ""
			if hash == 0 {
				hstr = "0"
			} else {
				for ; hash != 0; hash = hash >> 1 {
					hstr = string('0'+byte(hash&1)) + hstr
				}
			}
			d.logDebugHashMatch(m.name, pkgAndName, hstr, param)
			return true
		}
	}
	return false
}

// DebugHashMatchPos is similar to DebugHashMatchParam, but for hash computation
// it uses the source position including all inlining information instead of
// package name and path. The output trigger string is prefixed with "POS=" so
// that tools processing the output can reliably tell the difference. The mutex
// locking is also more frequent and more granular.
// Note that the default answer for no environment variable (d == nil)
// is "yes", do the thing.
func (d *HashDebug) DebugHashMatchPos(ctxt *obj.Link, pos src.XPos) bool {
	if d == nil {
		return true
	}
	if d.no {
		return false
	}
	// Written this way to make inlining likely.
	return d.debugHashMatchPos(ctxt, pos)
}

func (d *HashDebug) debugHashMatchPos(ctxt *obj.Link, pos src.XPos) bool {
	d.mu.Lock()
	defer d.mu.Unlock()

	b := d.bytesForPos(ctxt, pos)

	if d.yes {
		d.logDebugHashMatchLocked(d.name, string(b), "y", 0)
		return true
	}

	hash := hashOfBytes(b, 0)

	for _, m := range d.matches {
		if (m.hash^hash)&m.mask == 0 {
			hstr := ""
			if hash == 0 {
				hstr = "0"
			} else {
				for ; hash != 0; hash = hash >> 1 {
					hstr = string('0'+byte(hash&1)) + hstr
				}
			}
			d.logDebugHashMatchLocked(m.name, "POS="+string(b), hstr, 0)
			return true
		}
	}
	return false
}

// bytesForPos renders a position, including inlining, into d.bytesTmp
// and returns the byte array.  d.mu must be locked.
func (d *HashDebug) bytesForPos(ctxt *obj.Link, pos src.XPos) []byte {
	d.posTmp = ctxt.AllPos(pos, d.posTmp)
	// Reverse posTmp to put outermost first.
	b := &d.bytesTmp
	b.Reset()
	start := len(d.posTmp) - 1
	if d.inlineSuffixOnly {
		start = 0
	}
	for i := start; i >= 0; i-- {
		p := &d.posTmp[i]
		f := p.Filename()
		if d.fileSuffixOnly {
			f = filepath.Base(f)
		}
		fmt.Fprintf(b, "%s:%d:%d", f, p.Line(), p.Col())
		if i != 0 {
			b.WriteByte(';')
		}
	}
	return b.Bytes()
}

func (d *HashDebug) logDebugHashMatch(varname, name, hstr string, param uint64) {
	d.mu.Lock()
	defer d.mu.Unlock()
	d.logDebugHashMatchLocked(varname, name, hstr, param)
}

func (d *HashDebug) logDebugHashMatchLocked(varname, name, hstr string, param uint64) {
	file := d.logfile
	if file == nil {
		if tmpfile := os.Getenv("GSHS_LOGFILE"); tmpfile != "" {
			var err error
			file, err = os.OpenFile(tmpfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
			if err != nil {
				Fatalf("could not open hash-testing logfile %s", tmpfile)
				return
			}
		}
		if file == nil {
			file = os.Stdout
		}
		d.logfile = file
	}
	if len(hstr) > 24 {
		hstr = hstr[len(hstr)-24:]
	}
	// External tools depend on this string
	if param == 0 {
		fmt.Fprintf(file, "%s triggered %s %s\n", varname, name, hstr)
	} else {
		fmt.Fprintf(file, "%s triggered %s:%d %s\n", varname, name, param, hstr)
	}
	file.Sync()
}
