// 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)
}

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