// 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 "golang.org/x/debug/internal/core"

// A region is a piece of the virtual address space of the inferior.
// It has an address and a type.
// Note that it is the type of the thing in the region,
// not the type of the reference to the region.
type region struct {
	p   *core.Process
	a   core.Address
	typ *Type
}

// Address returns the address that a region of pointer type points to.
func (r region) Address() core.Address {
	if r.typ.Kind != KindPtr {
		panic("can't ask for the Address of a non-pointer " + r.typ.Name)
	}
	return r.p.ReadPtr(r.a)
}

// Int returns the int value stored in r.
func (r region) Int() int64 {
	if r.typ.Kind != KindInt || r.typ.Size != r.p.PtrSize() {
		panic("not an int: " + r.typ.Name)
	}
	return r.p.ReadInt(r.a)
}

// Uintptr returns the uintptr value stored in r.
func (r region) Uintptr() uint64 {
	if r.typ.Kind != KindUint || r.typ.Size != r.p.PtrSize() {
		panic("not a uintptr: " + r.typ.Name)
	}
	return r.p.ReadUintptr(r.a)
}

// Cast the region to the given type.
func (r region) Cast(typ *Type) region {
	return region{p: r.p, a: r.a, typ: typ}
}

// Deref loads from a pointer. r must contain a pointer.
func (r region) Deref() region {
	if r.typ.Kind != KindPtr {
		panic("can't deref on non-pointer: " + r.typ.Name)
	}
	if r.typ.Elem == nil {
		panic("can't deref unsafe.Pointer")
	}
	p := r.p.ReadPtr(r.a)
	return region{p: r.p, a: p, typ: r.typ.Elem}
}

// Uint64 returns the uint64 value stored in r.
// r must have type uint64.
func (r region) Uint64() uint64 {
	if r.typ.Kind != KindUint || r.typ.Size != 8 {
		panic("bad uint64 type " + r.typ.Name)
	}
	return r.p.ReadUint64(r.a)
}

// Uint32 returns the uint32 value stored in r.
// r must have type uint32.
func (r region) Uint32() uint32 {
	if r.typ.Kind != KindUint || r.typ.Size != 4 {
		panic("bad uint32 type " + r.typ.Name)
	}
	return r.p.ReadUint32(r.a)
}

// Int32 returns the int32 value stored in r.
// r must have type int32.
func (r region) Int32() int32 {
	if r.typ.Kind != KindInt || r.typ.Size != 4 {
		panic("bad int32 type " + r.typ.Name)
	}
	return r.p.ReadInt32(r.a)
}

// Uint16 returns the uint16 value stored in r.
// r must have type uint16.
func (r region) Uint16() uint16 {
	if r.typ.Kind != KindUint || r.typ.Size != 2 {
		panic("bad uint16 type " + r.typ.Name)
	}
	return r.p.ReadUint16(r.a)
}

// Uint8 returns the uint8 value stored in r.
// r must have type uint8.
func (r region) Uint8() uint8 {
	if r.typ.Kind != KindUint || r.typ.Size != 1 {
		panic("bad uint8 type " + r.typ.Name)
	}
	return r.p.ReadUint8(r.a)
}

// Bool returns the bool value stored in r.
// r must have type bool.
func (r region) Bool() bool {
	if r.typ.Kind != KindBool {
		panic("bad bool type " + r.typ.Name)
	}
	return r.p.ReadUint8(r.a) != 0
}

// String returns the value of the string stored in r.
func (r region) String() string {
	if r.typ.Kind != KindString {
		panic("bad string type " + r.typ.Name)
	}
	p := r.p.ReadPtr(r.a)
	n := r.p.ReadUintptr(r.a.Add(r.p.PtrSize()))
	b := make([]byte, n)
	r.p.ReadAt(b, p)
	return string(b)
}

// SliceIndex indexes a slice (a[n]). r must contain a slice.
// n must be in bounds for the slice.
func (r region) SliceIndex(n int64) region {
	if r.typ.Kind != KindSlice {
		panic("can't index a non-slice")
	}
	p := r.p.ReadPtr(r.a)
	return region{p: r.p, a: p.Add(n * r.typ.Elem.Size), typ: r.typ.Elem}
}

// SlicePtr returns the pointer inside a slice. r must contain a slice.
func (r region) SlicePtr() region {
	if r.typ.Kind != KindSlice {
		panic("can't Ptr a non-slice")
	}
	return region{p: r.p, a: r.a, typ: &Type{Name: "*" + r.typ.Name[2:], Size: r.p.PtrSize(), Kind: KindPtr, Elem: r.typ.Elem}}
}

// SliceLen returns the length of a slice. r must contain a slice.
func (r region) SliceLen() int64 {
	if r.typ.Kind != KindSlice {
		panic("can't len a non-slice")
	}
	return r.p.ReadInt(r.a.Add(r.p.PtrSize()))
}

// SliceCap returns the capacity of a slice. r must contain a slice.
func (r region) SliceCap() int64 {
	if r.typ.Kind != KindSlice {
		panic("can't cap a non-slice")
	}
	return r.p.ReadInt(r.a.Add(2 * r.p.PtrSize()))
}

// Field returns the part of r which contains the field f.
// r must contain a struct, and f must be one of its fields.
func (r region) Field(f string) region {
	finfo := r.typ.field(f)
	if finfo == nil {
		panic("can't find field " + r.typ.Name + "." + f)
	}
	return region{p: r.p, a: r.a.Add(finfo.Off), typ: finfo.Type}
}

func (r region) HasField(f string) bool {
	finfo := r.typ.field(f)
	return finfo != nil
}

func (r region) ArrayLen() int64 {
	if r.typ.Kind != KindArray {
		panic("can't ArrayLen a non-array")
	}
	return r.typ.Count
}

func (r region) ArrayIndex(i int64) region {
	if r.typ.Kind != KindArray {
		panic("can't ArrayIndex a non-array")
	}
	if i < 0 || i >= r.typ.Count {
		panic("array index out of bounds")
	}
	return region{p: r.p, a: r.a.Add(i * r.typ.Elem.Size), typ: r.typ.Elem}
}

func (r region) IsStruct() bool {
	return r.typ.Kind == KindStruct
}

func (r region) IsUint16() bool {
	return r.typ.Kind == KindUint && r.typ.Size == 2
}
