// Copyright 2021 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 encodemeta

// This package contains APIs and helpers for encoding the meta-data
// "blob" for a single Go package, created when coverage
// instrumentation is turned on.

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"hash"
	"hash/fnv"
	"internal/coverage"
	"internal/coverage/stringtab"
	"internal/coverage/uleb128"
	"io"
	"os"
)

type CoverageMetaDataBuilder struct {
	stab    stringtab.Writer
	funcs   []funcDesc
	tmp     []byte // temp work slice
	h       hash.Hash
	pkgpath uint32
	pkgname uint32
	modpath uint32
	debug   bool
	werr    error
}

func NewCoverageMetaDataBuilder(pkgpath string, pkgname string, modulepath string) (*CoverageMetaDataBuilder, error) {
	if pkgpath == "" {
		return nil, fmt.Errorf("invalid empty package path")
	}
	x := &CoverageMetaDataBuilder{
		tmp: make([]byte, 0, 256),
		h:   fnv.New128a(),
	}
	x.stab.InitWriter()
	x.stab.Lookup("")
	x.pkgpath = x.stab.Lookup(pkgpath)
	x.pkgname = x.stab.Lookup(pkgname)
	x.modpath = x.stab.Lookup(modulepath)
	io.WriteString(x.h, pkgpath)
	io.WriteString(x.h, pkgname)
	io.WriteString(x.h, modulepath)
	return x, nil
}

func h32(x uint32, h hash.Hash, tmp []byte) {
	tmp = tmp[:0]
	tmp = append(tmp, 0, 0, 0, 0)
	binary.LittleEndian.PutUint32(tmp, x)
	h.Write(tmp)
}

type funcDesc struct {
	encoded []byte
}

// AddFunc registers a new function with the meta data builder.
func (b *CoverageMetaDataBuilder) AddFunc(f coverage.FuncDesc) uint {
	hashFuncDesc(b.h, &f, b.tmp)
	fd := funcDesc{}
	b.tmp = b.tmp[:0]
	b.tmp = uleb128.AppendUleb128(b.tmp, uint(len(f.Units)))
	b.tmp = uleb128.AppendUleb128(b.tmp, uint(b.stab.Lookup(f.Funcname)))
	b.tmp = uleb128.AppendUleb128(b.tmp, uint(b.stab.Lookup(f.Srcfile)))
	for _, u := range f.Units {
		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.StLine))
		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.StCol))
		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.EnLine))
		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.EnCol))
		b.tmp = uleb128.AppendUleb128(b.tmp, uint(u.NxStmts))
	}
	lit := uint(0)
	if f.Lit {
		lit = 1
	}
	b.tmp = uleb128.AppendUleb128(b.tmp, lit)
	fd.encoded = bytes.Clone(b.tmp)
	rv := uint(len(b.funcs))
	b.funcs = append(b.funcs, fd)
	return rv
}

func (b *CoverageMetaDataBuilder) emitFuncOffsets(w io.WriteSeeker, off int64) int64 {
	nFuncs := len(b.funcs)
	var foff int64 = coverage.CovMetaHeaderSize + int64(b.stab.Size()) + int64(nFuncs)*4
	for idx := 0; idx < nFuncs; idx++ {
		b.wrUint32(w, uint32(foff))
		foff += int64(len(b.funcs[idx].encoded))
	}
	return off + (int64(len(b.funcs)) * 4)
}

func (b *CoverageMetaDataBuilder) emitFunc(w io.WriteSeeker, off int64, f funcDesc) (int64, error) {
	ew := len(f.encoded)
	if nw, err := w.Write(f.encoded); err != nil {
		return 0, err
	} else if ew != nw {
		return 0, fmt.Errorf("short write emitting coverage meta-data")
	}
	return off + int64(ew), nil
}

func (b *CoverageMetaDataBuilder) reportWriteError(err error) {
	if b.werr == nil {
		b.werr = err
	}
}

func (b *CoverageMetaDataBuilder) wrUint32(w io.WriteSeeker, v uint32) {
	b.tmp = b.tmp[:0]
	b.tmp = append(b.tmp, 0, 0, 0, 0)
	binary.LittleEndian.PutUint32(b.tmp, v)
	if nw, err := w.Write(b.tmp); err != nil {
		b.reportWriteError(err)
	} else if nw != 4 {
		b.reportWriteError(fmt.Errorf("short write"))
	}
}

// Emit writes the meta-data accumulated so far in this builder to 'w'.
// Returns a hash of the meta-data payload and an error.
func (b *CoverageMetaDataBuilder) Emit(w io.WriteSeeker) ([16]byte, error) {
	// Emit header.  Length will initially be zero, we'll
	// back-patch it later.
	var digest [16]byte
	copy(digest[:], b.h.Sum(nil))
	mh := coverage.MetaSymbolHeader{
		// hash and length initially zero, will be back-patched
		PkgPath:    uint32(b.pkgpath),
		PkgName:    uint32(b.pkgname),
		ModulePath: uint32(b.modpath),
		NumFiles:   uint32(b.stab.Nentries()),
		NumFuncs:   uint32(len(b.funcs)),
		MetaHash:   digest,
	}
	if b.debug {
		fmt.Fprintf(os.Stderr, "=-= writing header: %+v\n", mh)
	}
	if err := binary.Write(w, binary.LittleEndian, mh); err != nil {
		return digest, fmt.Errorf("error writing meta-file header: %v", err)
	}
	off := int64(coverage.CovMetaHeaderSize)

	// Write function offsets section
	off = b.emitFuncOffsets(w, off)

	// Check for any errors up to this point.
	if b.werr != nil {
		return digest, b.werr
	}

	// Write string table.
	if err := b.stab.Write(w); err != nil {
		return digest, err
	}
	off += int64(b.stab.Size())

	// Write functions
	for _, f := range b.funcs {
		var err error
		off, err = b.emitFunc(w, off, f)
		if err != nil {
			return digest, err
		}
	}

	// Back-patch the length.
	totalLength := uint32(off)
	if _, err := w.Seek(0, io.SeekStart); err != nil {
		return digest, err
	}
	b.wrUint32(w, totalLength)
	if b.werr != nil {
		return digest, b.werr
	}
	return digest, nil
}

// HashFuncDesc computes an md5 sum of a coverage.FuncDesc and returns
// a digest for it.
func HashFuncDesc(f *coverage.FuncDesc) [16]byte {
	h := fnv.New128a()
	tmp := make([]byte, 0, 32)
	hashFuncDesc(h, f, tmp)
	var r [16]byte
	copy(r[:], h.Sum(nil))
	return r
}

// hashFuncDesc incorporates a given function 'f' into the hash 'h'.
func hashFuncDesc(h hash.Hash, f *coverage.FuncDesc, tmp []byte) {
	io.WriteString(h, f.Funcname)
	io.WriteString(h, f.Srcfile)
	for _, u := range f.Units {
		h32(u.StLine, h, tmp)
		h32(u.StCol, h, tmp)
		h32(u.EnLine, h, tmp)
		h32(u.EnCol, h, tmp)
		h32(u.NxStmts, h, tmp)
	}
	lit := uint32(0)
	if f.Lit {
		lit = 1
	}
	h32(lit, h, tmp)
}
