// 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"
	"crypto/md5"
	"encoding/binary"
	"fmt"
	"hash"
	"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:   md5.New(),
	}
	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, []byte{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, []byte{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 := md5.New()
	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)
}
