// 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   *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.proc.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.proc.PtrSize() {
		panic("not an int: " + r.typ.Name)
	}
	return r.p.proc.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.proc.PtrSize() {
		panic("not a uintptr: " + r.typ.Name)
	}
	return r.p.proc.ReadUintptr(r.a)
}

// Cast the region to the given type.
func (r region) Cast(typ string) region {
	return region{p: r.p, a: r.a, typ: r.p.findType(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.proc.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.proc.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.proc.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.proc.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.proc.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.proc.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.proc.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.proc.ReadPtr(r.a)
	n := r.p.proc.ReadUintptr(r.a.Add(r.p.proc.PtrSize()))
	b := make([]byte, n)
	r.p.proc.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.proc.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.proc.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.proc.ReadInt(r.a.Add(r.p.proc.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.proc.ReadInt(r.a.Add(2 * r.p.proc.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
}
