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

// This package contains APIs and helpers for decoding a single package's
// meta data "blob" emitted by the compiler when coverage instrumentation
// is turned on.

import (
	"encoding/binary"
	"fmt"
	"internal/coverage"
	"internal/coverage/slicereader"
	"internal/coverage/stringtab"
	"os"
)

// See comments in the encodecovmeta package for details on the format.

type CoverageMetaDataDecoder struct {
	r      *slicereader.Reader
	hdr    coverage.MetaSymbolHeader
	strtab *stringtab.Reader
	tmp    []byte
	debug  bool
}

func NewCoverageMetaDataDecoder(b []byte, readonly bool) (*CoverageMetaDataDecoder, error) {
	slr := slicereader.NewReader(b, readonly)
	x := &CoverageMetaDataDecoder{
		r:   slr,
		tmp: make([]byte, 0, 256),
	}
	if err := x.readHeader(); err != nil {
		return nil, err
	}
	if err := x.readStringTable(); err != nil {
		return nil, err
	}
	return x, nil
}

func (d *CoverageMetaDataDecoder) readHeader() error {
	if err := binary.Read(d.r, binary.LittleEndian, &d.hdr); err != nil {
		return err
	}
	if d.debug {
		fmt.Fprintf(os.Stderr, "=-= after readHeader: %+v\n", d.hdr)
	}
	return nil
}

func (d *CoverageMetaDataDecoder) readStringTable() error {
	// Seek to the correct location to read the string table.
	stringTableLocation := int64(coverage.CovMetaHeaderSize + 4*d.hdr.NumFuncs)
	d.r.SeekTo(stringTableLocation)

	// Read the table itself.
	d.strtab = stringtab.NewReader(d.r)
	d.strtab.Read()
	return nil
}

func (d *CoverageMetaDataDecoder) PackagePath() string {
	return d.strtab.Get(d.hdr.PkgPath)
}

func (d *CoverageMetaDataDecoder) PackageName() string {
	return d.strtab.Get(d.hdr.PkgName)
}

func (d *CoverageMetaDataDecoder) ModulePath() string {
	return d.strtab.Get(d.hdr.ModulePath)
}

func (d *CoverageMetaDataDecoder) NumFuncs() uint32 {
	return d.hdr.NumFuncs
}

// ReadFunc reads the coverage meta-data for the function with index
// 'findex', filling it into the FuncDesc pointed to by 'f'.
func (d *CoverageMetaDataDecoder) ReadFunc(fidx uint32, f *coverage.FuncDesc) error {
	if fidx >= d.hdr.NumFuncs {
		return fmt.Errorf("illegal function index")
	}

	// Seek to the correct location to read the function offset and read it.
	funcOffsetLocation := int64(coverage.CovMetaHeaderSize + 4*fidx)
	d.r.SeekTo(funcOffsetLocation)
	foff := d.r.ReadUint32()

	// Check assumptions
	if foff < uint32(funcOffsetLocation) || foff > d.hdr.Length {
		return fmt.Errorf("malformed func offset %d", foff)
	}

	// Seek to the correct location to read the function.
	d.r.SeekTo(int64(foff))

	// Preamble containing number of units, file, and function.
	numUnits := uint32(d.r.ReadULEB128())
	fnameidx := uint32(d.r.ReadULEB128())
	fileidx := uint32(d.r.ReadULEB128())

	f.Srcfile = d.strtab.Get(fileidx)
	f.Funcname = d.strtab.Get(fnameidx)

	// Now the units
	f.Units = f.Units[:0]
	if cap(f.Units) < int(numUnits) {
		f.Units = make([]coverage.CoverableUnit, 0, numUnits)
	}
	for k := uint32(0); k < numUnits; k++ {
		f.Units = append(f.Units,
			coverage.CoverableUnit{
				StLine:  uint32(d.r.ReadULEB128()),
				StCol:   uint32(d.r.ReadULEB128()),
				EnLine:  uint32(d.r.ReadULEB128()),
				EnCol:   uint32(d.r.ReadULEB128()),
				NxStmts: uint32(d.r.ReadULEB128()),
			})
	}
	lit := d.r.ReadULEB128()
	f.Lit = lit != 0
	return nil
}
