// Copyright 2019 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 goobj

import (
	"bytes"
	"cmd/internal/objabi"
	"encoding/binary"
)

// CUFileIndex is used to index the filenames that are stored in the
// per-package/per-CU FileList.
type CUFileIndex uint32

// FuncInfo is serialized as a symbol (aux symbol). The symbol data is
// the binary encoding of the struct below.
//
// TODO: make each pcdata a separate symbol?
type FuncInfo struct {
	Args   uint32
	Locals uint32
	FuncID objabi.FuncID

	Pcsp        uint32
	Pcfile      uint32
	Pcline      uint32
	Pcinline    uint32
	Pcdata      []uint32
	PcdataEnd   uint32
	Funcdataoff []uint32
	File        []CUFileIndex

	InlTree []InlTreeNode
}

func (a *FuncInfo) Write(w *bytes.Buffer) {
	var b [4]byte
	writeUint32 := func(x uint32) {
		binary.LittleEndian.PutUint32(b[:], x)
		w.Write(b[:])
	}

	writeUint32(a.Args)
	writeUint32(a.Locals)
	writeUint32(uint32(a.FuncID))

	writeUint32(a.Pcsp)
	writeUint32(a.Pcfile)
	writeUint32(a.Pcline)
	writeUint32(a.Pcinline)
	writeUint32(uint32(len(a.Pcdata)))
	for _, x := range a.Pcdata {
		writeUint32(x)
	}
	writeUint32(a.PcdataEnd)
	writeUint32(uint32(len(a.Funcdataoff)))
	for _, x := range a.Funcdataoff {
		writeUint32(x)
	}
	writeUint32(uint32(len(a.File)))
	for _, f := range a.File {
		writeUint32(uint32(f))
	}
	writeUint32(uint32(len(a.InlTree)))
	for i := range a.InlTree {
		a.InlTree[i].Write(w)
	}
}

func (a *FuncInfo) Read(b []byte) {
	readUint32 := func() uint32 {
		x := binary.LittleEndian.Uint32(b)
		b = b[4:]
		return x
	}

	a.Args = readUint32()
	a.Locals = readUint32()
	a.FuncID = objabi.FuncID(readUint32())

	a.Pcsp = readUint32()
	a.Pcfile = readUint32()
	a.Pcline = readUint32()
	a.Pcinline = readUint32()
	pcdatalen := readUint32()
	a.Pcdata = make([]uint32, pcdatalen)
	for i := range a.Pcdata {
		a.Pcdata[i] = readUint32()
	}
	a.PcdataEnd = readUint32()
	funcdataofflen := readUint32()
	a.Funcdataoff = make([]uint32, funcdataofflen)
	for i := range a.Funcdataoff {
		a.Funcdataoff[i] = readUint32()
	}
	filelen := readUint32()
	a.File = make([]CUFileIndex, filelen)
	for i := range a.File {
		a.File[i] = CUFileIndex(readUint32())
	}
	inltreelen := readUint32()
	a.InlTree = make([]InlTreeNode, inltreelen)
	for i := range a.InlTree {
		b = a.InlTree[i].Read(b)
	}
}

// FuncInfoLengths is a cache containing a roadmap of offsets and
// lengths for things within a serialized FuncInfo. Each length field
// stores the number of items (e.g. files, inltree nodes, etc), and the
// corresponding "off" field stores the byte offset of the start of
// the items in question.
type FuncInfoLengths struct {
	NumPcdata      uint32
	PcdataOff      uint32
	NumFuncdataoff uint32
	FuncdataoffOff uint32
	NumFile        uint32
	FileOff        uint32
	NumInlTree     uint32
	InlTreeOff     uint32
	Initialized    bool
}

func (*FuncInfo) ReadFuncInfoLengths(b []byte) FuncInfoLengths {
	var result FuncInfoLengths

	const numpcdataOff = 28
	result.NumPcdata = binary.LittleEndian.Uint32(b[numpcdataOff:])
	result.PcdataOff = numpcdataOff + 4

	numfuncdataoffOff := result.PcdataOff + 4*(result.NumPcdata+1)
	result.NumFuncdataoff = binary.LittleEndian.Uint32(b[numfuncdataoffOff:])
	result.FuncdataoffOff = numfuncdataoffOff + 4

	numfileOff := result.FuncdataoffOff + 4*result.NumFuncdataoff
	result.NumFile = binary.LittleEndian.Uint32(b[numfileOff:])
	result.FileOff = numfileOff + 4

	numinltreeOff := result.FileOff + 4*result.NumFile
	result.NumInlTree = binary.LittleEndian.Uint32(b[numinltreeOff:])
	result.InlTreeOff = numinltreeOff + 4

	result.Initialized = true

	return result
}

func (*FuncInfo) ReadArgs(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }

func (*FuncInfo) ReadLocals(b []byte) uint32 { return binary.LittleEndian.Uint32(b[4:]) }

func (*FuncInfo) ReadFuncID(b []byte) uint32 { return binary.LittleEndian.Uint32(b[8:]) }

// return start and end offsets.
func (*FuncInfo) ReadPcsp(b []byte) (uint32, uint32) {
	return binary.LittleEndian.Uint32(b[12:]), binary.LittleEndian.Uint32(b[16:])
}

// return start and end offsets.
func (*FuncInfo) ReadPcfile(b []byte) (uint32, uint32) {
	return binary.LittleEndian.Uint32(b[16:]), binary.LittleEndian.Uint32(b[20:])
}

// return start and end offsets.
func (*FuncInfo) ReadPcline(b []byte) (uint32, uint32) {
	return binary.LittleEndian.Uint32(b[20:]), binary.LittleEndian.Uint32(b[24:])
}

// return start and end offsets.
func (*FuncInfo) ReadPcinline(b []byte, pcdataoffset uint32) (uint32, uint32) {
	return binary.LittleEndian.Uint32(b[24:]), binary.LittleEndian.Uint32(b[pcdataoffset:])
}

// return start and end offsets.
func (*FuncInfo) ReadPcdata(b []byte, pcdataoffset uint32, k uint32) (uint32, uint32) {
	return binary.LittleEndian.Uint32(b[pcdataoffset+4*k:]), binary.LittleEndian.Uint32(b[pcdataoffset+4+4*k:])
}

func (*FuncInfo) ReadFuncdataoff(b []byte, funcdataofffoff uint32, k uint32) int64 {
	return int64(binary.LittleEndian.Uint32(b[funcdataofffoff+4*k:]))
}

func (*FuncInfo) ReadFile(b []byte, filesoff uint32, k uint32) CUFileIndex {
	return CUFileIndex(binary.LittleEndian.Uint32(b[filesoff+4*k:]))
}

func (*FuncInfo) ReadInlTree(b []byte, inltreeoff uint32, k uint32) InlTreeNode {
	const inlTreeNodeSize = 4 * 6
	var result InlTreeNode
	result.Read(b[inltreeoff+k*inlTreeNodeSize:])
	return result
}

// InlTreeNode is the serialized form of FileInfo.InlTree.
type InlTreeNode struct {
	Parent   int32
	File     CUFileIndex
	Line     int32
	Func     SymRef
	ParentPC int32
}

func (inl *InlTreeNode) Write(w *bytes.Buffer) {
	var b [4]byte
	writeUint32 := func(x uint32) {
		binary.LittleEndian.PutUint32(b[:], x)
		w.Write(b[:])
	}
	writeUint32(uint32(inl.Parent))
	writeUint32(uint32(inl.File))
	writeUint32(uint32(inl.Line))
	writeUint32(inl.Func.PkgIdx)
	writeUint32(inl.Func.SymIdx)
	writeUint32(uint32(inl.ParentPC))
}

// Read an InlTreeNode from b, return the remaining bytes.
func (inl *InlTreeNode) Read(b []byte) []byte {
	readUint32 := func() uint32 {
		x := binary.LittleEndian.Uint32(b)
		b = b[4:]
		return x
	}
	inl.Parent = int32(readUint32())
	inl.File = CUFileIndex(readUint32())
	inl.Line = int32(readUint32())
	inl.Func = SymRef{readUint32(), readUint32()}
	inl.ParentPC = int32(readUint32())
	return b
}
