// Copyright 2017 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 gocore

import (
	"encoding/binary"
	"unsafe"

	"golang.org/x/debug/internal/core"
)

// A Root is an area of memory that might have pointers into the Go heap.
type Root struct {
	Name string
	Type *Type // always non-nil
	// Frame, if non-nil, points to the frame in which this root lives.
	// Roots with non-nil Frame fields refer to local variables on a stack.
	// A stack root might be a large type, with some of its fields live and
	// others dead. Consult Frame.Live to find out which pointers in a stack
	// root are live.
	Frame *Frame

	pieces []rootPiece
	id     int
}

// HasAddress returns true if the root is simple and contiguous, and can be
// described with just a single address.
func (r *Root) HasAddress() bool {
	return len(r.pieces) == 1 && r.pieces[0].kind == addrPiece
}

// Addr returns the address of the root, if it has one.
func (r *Root) Addr() core.Address {
	if r.HasAddress() {
		return core.Address(r.pieces[0].value)
	}
	return 0
}

func (p *Process) makeMemRoot(name string, typ *Type, fr *Frame, addr core.Address) *Root {
	return makeMemRoot(&p.nRoots, name, typ, fr, addr)
}

func makeMemRoot(nRoots *int, name string, typ *Type, fr *Frame, addr core.Address) *Root {
	r := &Root{
		Name:   name,
		Type:   typ,
		Frame:  fr,
		pieces: []rootPiece{{size: typ.Size, kind: addrPiece, value: uint64(addr)}},
		id:     *nRoots,
	}
	*nRoots += 1
	return r
}

func (p *Process) makeCompositeRoot(name string, typ *Type, fr *Frame, pieces []rootPiece) *Root {
	r := &Root{
		Name:   name,
		Type:   typ,
		Frame:  fr,
		pieces: pieces,
		id:     p.nRoots,
	}
	p.nRoots++
	return r
}

func (pr *Process) readRootPtr(r *Root, offset int64) core.Address {
	// TODO(mknyszek): Little-endian only.
	ptrBuf := make([]byte, pr.proc.PtrSize())
	pr.readRootAt(r, ptrBuf, offset)
	if pr.proc.PtrSize() == 4 {
		return core.Address(binary.LittleEndian.Uint32(ptrBuf))
	}
	return core.Address(binary.LittleEndian.Uint64(ptrBuf))
}

// ReadRootAt reads data out of this root. offset+len(b) must be less than r.Type.Size.
// Returns the address read from, if the read was contiguous and from memory.
func (pr *Process) readRootAt(r *Root, b []byte, offset int64) core.Address {
	if offset+int64(len(b)) > r.Type.Size {
		panic("invalid range to read from root")
	}
	if len(b) == 0 {
		return 0
	}
	bOff := int64(0)
	var addr core.Address
	first := true
	for _, p := range r.pieces {
		if offset > p.off+p.size {
			continue
		}
		if offset+int64(len(b)) <= p.off {
			break
		}
		pOff := max(p.off, offset)
		base := pOff - p.off
		rlen := min(int64(len(b))-bOff, p.size-base)
		switch p.kind {
		case addrPiece:
			pr.proc.ReadAt(b[bOff:bOff+rlen], core.Address(p.value).Add(base))
			if first {
				addr = core.Address(p.value).Add(base)
			} else {
				addr = 0
			}
		case regPiece, immPiece:
			// TODO(mknyszek): Supports little-endian only.
			v := ((*[8]byte)(unsafe.Pointer(&p.value)))[:p.size]
			copy(b[bOff:bOff+rlen], v[base:base+rlen])
			addr = 0
		}
		if first {
			first = false
		}
		bOff += rlen
		if bOff == int64(len(b)) {
			break
		}
	}
	return addr
}

// walkRootTypePtrs calls fn for the edges found in an object of type t living at offset off in the root r.
// If fn returns false, return immediately with false.
func walkRootTypePtrs(p *Process, r *Root, ptrBuf []byte, off int64, t *Type, fn func(int64, Object, int64) bool) bool {
	switch t.Kind {
	case KindBool, KindInt, KindUint, KindFloat, KindComplex:
		// no edges here
	case KindIface, KindEface:
		// The first word is a type or itab.
		// Itabs are never in the heap.
		// Types might be, though.
		// We have no idea about the liveness of registers, when a == 0.
		a := p.readRootAt(r, ptrBuf[:p.proc.PtrSize()], off)
		if a != 0 && (r.Frame == nil || r.Frame.Live[a]) {
			var ptr core.Address
			if p.proc.PtrSize() == 4 {
				ptr = core.Address(binary.LittleEndian.Uint32(ptrBuf[:]))
			} else {
				ptr = core.Address(binary.LittleEndian.Uint64(ptrBuf[:]))
			}
			dst, off2 := p.FindObject(ptr)
			if dst != 0 {
				if !fn(off, dst, off2) {
					return false
				}
			}
		}
		// Treat second word like a pointer.
		off += p.proc.PtrSize()
		fallthrough
	case KindPtr, KindString, KindSlice, KindFunc:
		a := p.readRootAt(r, ptrBuf[:p.proc.PtrSize()], off)
		if a != 0 && (r.Frame == nil || r.Frame.Live[a]) {
			var ptr core.Address
			if p.proc.PtrSize() == 4 {
				ptr = core.Address(binary.LittleEndian.Uint32(ptrBuf[:]))
			} else {
				ptr = core.Address(binary.LittleEndian.Uint64(ptrBuf[:]))
			}
			dst, off2 := p.FindObject(ptr)
			if dst != 0 {
				if !fn(off, dst, off2) {
					return false
				}
			}
		}
	case KindArray:
		s := t.Elem.Size
		for i := int64(0); i < t.Count; i++ {
			if !walkRootTypePtrs(p, r, ptrBuf, off+i*s, t.Elem, fn) {
				return false
			}
		}
	case KindStruct:
		for _, f := range t.Fields {
			if !walkRootTypePtrs(p, r, ptrBuf, off+f.Off, f.Type, fn) {
				return false
			}
		}
	}
	return true
}

type rootPieceKind int

const (
	addrPiece rootPieceKind = iota
	regPiece
	immPiece
)

type rootPiece struct {
	off   int64         // Logical offset into the root, or specifically the root's Type.
	size  int64         // Size of the piece.
	kind  rootPieceKind // Where the piece is.
	value uint64        // Address if kind == AddrPiece, value if kind == RegPiece or kind == ImmPiece.
}
