// 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\n", 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, os.SEEK_SET); 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)
}
