// 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 encodecounter

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"internal/coverage"
	"internal/coverage/slicewriter"
	"internal/coverage/stringtab"
	"internal/coverage/uleb128"
	"io"
	"os"
	"sort"
)

// This package contains APIs and helpers for encoding initial portions
// of the counter data files emitted at runtime when coverage instrumention
// is enabled.  Counter data files may contain multiple segments; the file
// header and first segment are written via the "Write" method below, and
// additional segments can then be added using "AddSegment".

type CoverageDataWriter struct {
	stab    *stringtab.Writer
	w       *bufio.Writer
	tmp     []byte
	cflavor coverage.CounterFlavor
	segs    uint32
	debug   bool
}

func NewCoverageDataWriter(w io.Writer, flav coverage.CounterFlavor) *CoverageDataWriter {
	r := &CoverageDataWriter{
		stab: &stringtab.Writer{},
		w:    bufio.NewWriter(w),

		tmp:     make([]byte, 64),
		cflavor: flav,
	}
	r.stab.InitWriter()
	r.stab.Lookup("")
	return r
}

// CounterVisitor describes a helper object used during counter file
// writing; when writing counter data files, clients pass a
// CounterVisitor to the write/emit routines. The writers will then
// first invoke the visitor's NumFuncs() method to find out how many
// function's worth of data to write, then it will invoke VisitFuncs.
// The expectation is that the VisitFuncs method will then invoke the
// callback "f" with data for each function to emit to the file.
type CounterVisitor interface {
	NumFuncs() (int, error)
	VisitFuncs(f CounterVisitorFn) error
}

// CounterVisitorFn describes a callback function invoked when writing
// coverage counter data.
type CounterVisitorFn func(pkid uint32, funcid uint32, counters []uint32) error

// Write writes the contents of the count-data file to the writer
// previously supplied to NewCoverageDataWriter. Returns an error
// if something went wrong somewhere with the write.
func (cfw *CoverageDataWriter) Write(metaFileHash [16]byte, args map[string]string, visitor CounterVisitor) error {
	if err := cfw.writeHeader(metaFileHash); err != nil {
		return err
	}
	return cfw.AppendSegment(args, visitor)
}

func padToFourByteBoundary(ws *slicewriter.WriteSeeker) error {
	sz := len(ws.BytesWritten())
	zeros := []byte{0, 0, 0, 0}
	rem := uint32(sz) % 4
	if rem != 0 {
		pad := zeros[:(4 - rem)]
		if nw, err := ws.Write(pad); err != nil {
			return err
		} else if nw != len(pad) {
			return fmt.Errorf("error: short write")
		}
	}
	return nil
}

func (cfw *CoverageDataWriter) writeSegmentPreamble(args map[string]string, visitor CounterVisitor) error {
	var csh coverage.CounterSegmentHeader
	if nf, err := visitor.NumFuncs(); err != nil {
		return err
	} else {
		csh.FcnEntries = uint64(nf)
	}

	// Write string table and args to a byte slice (since we need
	// to capture offsets at various points), then emit the slice
	// once we are done.
	cfw.stab.Freeze()
	ws := &slicewriter.WriteSeeker{}
	if err := cfw.stab.Write(ws); err != nil {
		return err
	}
	csh.StrTabLen = uint32(len(ws.BytesWritten()))

	akeys := make([]string, 0, len(args))
	for k := range args {
		akeys = append(akeys, k)
	}
	sort.Strings(akeys)

	wrULEB128 := func(v uint) error {
		cfw.tmp = cfw.tmp[:0]
		cfw.tmp = uleb128.AppendUleb128(cfw.tmp, v)
		if _, err := ws.Write(cfw.tmp); err != nil {
			return err
		}
		return nil
	}

	// Count of arg pairs.
	if err := wrULEB128(uint(len(args))); err != nil {
		return err
	}
	// Arg pairs themselves.
	for _, k := range akeys {
		ki := uint(cfw.stab.Lookup(k))
		if err := wrULEB128(ki); err != nil {
			return err
		}
		v := args[k]
		vi := uint(cfw.stab.Lookup(v))
		if err := wrULEB128(vi); err != nil {
			return err
		}
	}
	if err := padToFourByteBoundary(ws); err != nil {
		return err
	}
	csh.ArgsLen = uint32(len(ws.BytesWritten())) - csh.StrTabLen

	if cfw.debug {
		fmt.Fprintf(os.Stderr, "=-= counter segment header: %+v", csh)
		fmt.Fprintf(os.Stderr, " FcnEntries=0x%x StrTabLen=0x%x ArgsLen=0x%x\n",
			csh.FcnEntries, csh.StrTabLen, csh.ArgsLen)
	}

	// At this point we can now do the actual write.
	if err := binary.Write(cfw.w, binary.LittleEndian, csh); err != nil {
		return err
	}
	if err := cfw.writeBytes(ws.BytesWritten()); err != nil {
		return err
	}
	return nil
}

// AppendSegment appends a new segment to a counter data, with a new
// args section followed by a payload of counter data clauses.
func (cfw *CoverageDataWriter) AppendSegment(args map[string]string, visitor CounterVisitor) error {
	cfw.stab = &stringtab.Writer{}
	cfw.stab.InitWriter()
	cfw.stab.Lookup("")

	var err error
	for k, v := range args {
		cfw.stab.Lookup(k)
		cfw.stab.Lookup(v)
	}

	if err = cfw.writeSegmentPreamble(args, visitor); err != nil {
		return err
	}
	if err = cfw.writeCounters(visitor); err != nil {
		return err
	}
	if err = cfw.writeFooter(); err != nil {
		return err
	}
	if err := cfw.w.Flush(); err != nil {
		return fmt.Errorf("write error: %v\n", err)
	}
	cfw.stab = nil
	return nil
}

func (cfw *CoverageDataWriter) writeHeader(metaFileHash [16]byte) error {
	// Emit file header.
	ch := coverage.CounterFileHeader{
		Magic:     coverage.CovCounterMagic,
		Version:   coverage.CounterFileVersion,
		MetaHash:  metaFileHash,
		CFlavor:   cfw.cflavor,
		BigEndian: false,
	}
	if err := binary.Write(cfw.w, binary.LittleEndian, ch); err != nil {
		return err
	}
	return nil
}

func (cfw *CoverageDataWriter) writeBytes(b []byte) error {
	if len(b) == 0 {
		return nil
	}
	nw, err := cfw.w.Write(b)
	if err != nil {
		return fmt.Errorf("error writing counter data: %v", err)
	}
	if len(b) != nw {
		return fmt.Errorf("error writing counter data: short write\n")
	}
	return nil
}

func (cfw *CoverageDataWriter) writeCounters(visitor CounterVisitor) error {
	// Notes:
	// - this version writes everything little-endian, which means
	//   a call is needed to encode every value (expensive)
	// - we may want to move to a model in which we just blast out
	//   all counters, or possibly mmap the file and do the write
	//   implicitly.
	ctrb := make([]byte, 4)
	wrval := func(val uint32) error {
		var buf []byte
		var towr int
		if cfw.cflavor == coverage.CtrRaw {
			binary.LittleEndian.PutUint32(ctrb, val)
			buf = ctrb
			towr = 4
		} else if cfw.cflavor == coverage.CtrULeb128 {
			cfw.tmp = cfw.tmp[:0]
			cfw.tmp = uleb128.AppendUleb128(cfw.tmp, uint(val))
			buf = cfw.tmp
			towr = len(buf)
		} else {
			panic("internal error: bad counter flavor")
		}
		if sz, err := cfw.w.Write(buf); err != nil {
			return err
		} else if sz != towr {
			return fmt.Errorf("writing counters: short write")
		}
		return nil
	}

	// Write out entries for each live function.
	emitter := func(pkid uint32, funcid uint32, counters []uint32) error {
		if err := wrval(uint32(len(counters))); err != nil {
			return err
		}

		if err := wrval(pkid); err != nil {
			return err
		}

		if err := wrval(funcid); err != nil {
			return err
		}
		for _, val := range counters {
			if err := wrval(val); err != nil {
				return err
			}
		}
		return nil
	}
	if err := visitor.VisitFuncs(emitter); err != nil {
		return err
	}
	return nil
}

func (cfw *CoverageDataWriter) writeFooter() error {
	cfw.segs++
	cf := coverage.CounterFileFooter{
		Magic:       coverage.CovCounterMagic,
		NumSegments: cfw.segs,
	}
	if err := binary.Write(cfw.w, binary.LittleEndian, cf); err != nil {
		return err
	}
	return nil
}
