// Copyright 2015 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.

// Functions for reading values of various types from a program's memory.

package server

import (
	"errors"
	"fmt"

	"golang.org/x/debug/dwarf"
)

// peekBytes reads len(buf) bytes at addr.
func (s *Server) peekBytes(addr uint64, buf []byte) error {
	return s.ptracePeek(s.stoppedPid, uintptr(addr), buf)
}

// peekPtr reads a pointer at addr.
func (s *Server) peekPtr(addr uint64) (uint64, error) {
	buf := make([]byte, s.arch.PointerSize)
	if err := s.peekBytes(addr, buf); err != nil {
		return 0, err
	}
	return s.arch.Uintptr(buf), nil
}

// peekUint8 reads a single byte at addr.
func (s *Server) peekUint8(addr uint64) (byte, error) {
	buf := make([]byte, 1)
	if err := s.peekBytes(addr, buf); err != nil {
		return 0, err
	}
	return uint8(s.arch.UintN(buf)), nil
}

// peekInt reads an int of size n bytes at addr.
func (s *Server) peekInt(addr uint64, n int64) (int64, error) {
	buf := make([]byte, n)
	if err := s.peekBytes(addr, buf); err != nil {
		return 0, err
	}
	return s.arch.IntN(buf), nil
}

// peekUint reads a uint of size n bytes at addr.
func (s *Server) peekUint(addr uint64, n int64) (uint64, error) {
	buf := make([]byte, n)
	if err := s.peekBytes(addr, buf); err != nil {
		return 0, err
	}
	return s.arch.UintN(buf), nil
}

// peekString reads a string of the given type at the given address.
// At most byteLimit bytes will be read.  If the string is longer, "..." is appended.
func (s *Server) peekString(typ *dwarf.StringType, a uint64, byteLimit uint64) (string, error) {
	ptr, err := s.peekPtrStructField(&typ.StructType, a, "str")
	if err != nil {
		return "", err
	}
	length, err := s.peekUintOrIntStructField(&typ.StructType, a, "len")
	if err != nil {
		return "", err
	}
	if length > byteLimit {
		buf := make([]byte, byteLimit, byteLimit+3)
		if err := s.peekBytes(ptr, buf); err != nil {
			return "", err
		} else {
			buf = append(buf, '.', '.', '.')
			return string(buf), nil
		}
	} else {
		buf := make([]byte, length)
		if err := s.peekBytes(ptr, buf); err != nil {
			return "", err
		} else {
			return string(buf), nil
		}
	}
}

// peekCString reads a NUL-terminated string at the given address.
// At most byteLimit bytes will be read.  If the string is longer, "..." is appended.
// peekCString never returns errors; if an error occurs, the string will be truncated in some way.
func (s *Server) peekCString(a uint64, byteLimit uint64) string {
	buf := make([]byte, byteLimit, byteLimit+3)
	s.peekBytes(a, buf)
	for i, c := range buf {
		if c == 0 {
			return string(buf[0:i])
		}
	}
	buf = append(buf, '.', '.', '.')
	return string(buf)
}

// peekPtrStructField reads a pointer in the field fieldName of the struct
// of type t at addr.
func (s *Server) peekPtrStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) {
	f, err := getField(t, fieldName)
	if err != nil {
		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
	}
	if _, ok := f.Type.(*dwarf.PtrType); !ok {
		return 0, fmt.Errorf("field %s is not a pointer", fieldName)
	}
	return s.peekPtr(addr + uint64(f.ByteOffset))
}

// peekUintOrIntStructField reads a signed or unsigned integer in the field fieldName
// of the struct of type t at addr. If the value is negative, it returns an error.
// This function is used when the value should be non-negative, but the DWARF
// type of the field may be signed or unsigned.
func (s *Server) peekUintOrIntStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) {
	f, err := getField(t, fieldName)
	if err != nil {
		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
	}
	ut, ok := f.Type.(*dwarf.UintType)
	if ok {
		return s.peekUint(addr+uint64(f.ByteOffset), ut.ByteSize)
	}
	it, ok := f.Type.(*dwarf.IntType)
	if !ok {
		return 0, fmt.Errorf("field %s is not an integer", fieldName)
	}
	i, err := s.peekInt(addr+uint64(f.ByteOffset), it.ByteSize)
	if err != nil {
		return 0, err
	}
	if i < 0 {
		return 0, fmt.Errorf("field %s is negative", fieldName)
	}
	return uint64(i), nil
}

// peekUintStructField reads a uint in the field fieldName of the struct
// of type t at addr.  The size of the uint is determined by the field.
func (s *Server) peekUintStructField(t *dwarf.StructType, addr uint64, fieldName string) (uint64, error) {
	f, err := getField(t, fieldName)
	if err != nil {
		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
	}
	ut, ok := f.Type.(*dwarf.UintType)
	if !ok {
		return 0, fmt.Errorf("field %s is not an unsigned integer", fieldName)
	}
	return s.peekUint(addr+uint64(f.ByteOffset), ut.ByteSize)
}

// peekIntStructField reads an int in the field fieldName of the struct
// of type t at addr.  The size of the int is determined by the field.
func (s *Server) peekIntStructField(t *dwarf.StructType, addr uint64, fieldName string) (int64, error) {
	f, err := getField(t, fieldName)
	if err != nil {
		return 0, fmt.Errorf("reading field %s: %s", fieldName, err)
	}
	it, ok := f.Type.(*dwarf.IntType)
	if !ok {
		return 0, fmt.Errorf("field %s is not a signed integer", fieldName)
	}
	return s.peekInt(addr+uint64(f.ByteOffset), it.ByteSize)
}

// peekStringStructField reads a string field from the struct of the given type
// at the given address.
// At most byteLimit bytes will be read.  If the string is longer, "..." is appended.
func (s *Server) peekStringStructField(t *dwarf.StructType, addr uint64, fieldName string, byteLimit uint64) (string, error) {
	f, err := getField(t, fieldName)
	if err != nil {
		return "", fmt.Errorf("reading field %s: %s", fieldName, err)
	}
	st, ok := followTypedefs(f.Type).(*dwarf.StringType)
	if !ok {
		return "", fmt.Errorf("field %s is not a string", fieldName)
	}
	return s.peekString(st, addr+uint64(f.ByteOffset), byteLimit)
}

// peekMapLocationAndType returns the address and DWARF type of the underlying
// struct of a map variable.
func (s *Server) peekMapLocationAndType(t *dwarf.MapType, a uint64) (uint64, *dwarf.StructType, error) {
	// Maps are pointers to structs.
	pt, ok := t.Type.(*dwarf.PtrType)
	if !ok {
		return 0, nil, errors.New("bad map type: not a pointer")
	}
	st, ok := pt.Type.(*dwarf.StructType)
	if !ok {
		return 0, nil, errors.New("bad map type: not a pointer to a struct")
	}
	// a is the address of a pointer to a struct.  Get the pointer's value.
	a, err := s.peekPtr(a)
	if err != nil {
		return 0, nil, fmt.Errorf("reading map pointer: %s", err)
	}
	return a, st, nil
}

// peekMapValues reads a map at the given address and calls fn with the addresses for each (key, value) pair.
// If fn returns false, peekMapValues stops.
func (s *Server) peekMapValues(t *dwarf.MapType, a uint64, fn func(keyAddr, valAddr uint64, keyType, valType dwarf.Type) bool) error {
	a, st, err := s.peekMapLocationAndType(t, a)
	if err != nil {
		return err
	}
	if a == 0 {
		// The pointer was nil, so the map is empty.
		return nil
	}
	// Gather information about the struct type and the map bucket type.
	b, err := s.peekUintStructField(st, a, "B")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	buckets, err := s.peekPtrStructField(st, a, "buckets")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	oldbuckets, err := s.peekPtrStructField(st, a, "oldbuckets")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	bf, err := getField(st, "buckets")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	bucketPtrType, ok := bf.Type.(*dwarf.PtrType)
	if !ok {
		return errors.New("bad map bucket type: not a pointer")
	}
	bt, ok := bucketPtrType.Type.(*dwarf.StructType)
	if !ok {
		return errors.New("bad map bucket type: not a pointer to a struct")
	}
	bucketSize := uint64(bucketPtrType.Type.Size())
	tophashField, err := getField(bt, "tophash")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	bucketCnt := uint64(tophashField.Type.Size())
	tophashFieldOffset := uint64(tophashField.ByteOffset)
	keysField, err := getField(bt, "keys")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	keysType, ok := keysField.Type.(*dwarf.ArrayType)
	if !ok {
		return errors.New(`bad map bucket type: "keys" is not an array`)
	}
	keyType := keysType.Type
	keysStride := uint64(keysType.StrideBitSize / 8)
	keysFieldOffset := uint64(keysField.ByteOffset)
	valuesField, err := getField(bt, "values")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	valuesType, ok := valuesField.Type.(*dwarf.ArrayType)
	if !ok {
		return errors.New(`bad map bucket type: "values" is not an array`)
	}
	valueType := valuesType.Type
	valuesStride := uint64(valuesType.StrideBitSize / 8)
	valuesFieldOffset := uint64(valuesField.ByteOffset)
	overflowField, err := getField(bt, "overflow")
	if err != nil {
		return fmt.Errorf("reading map: %s", err)
	}
	overflowFieldOffset := uint64(overflowField.ByteOffset)

	// Iterate through the two arrays of buckets.
	bucketArrays := [2]struct {
		addr uint64
		size uint64
	}{
		{buckets, 1 << b},
		{oldbuckets, 1 << (b - 1)},
	}
	for _, bucketArray := range bucketArrays {
		if bucketArray.addr == 0 {
			continue
		}
		for i := uint64(0); i < bucketArray.size; i++ {
			bucketAddr := bucketArray.addr + i*bucketSize
			// Iterate through the linked list of buckets.
			// TODO: check for repeated bucket pointers.
			for bucketAddr != 0 {
				// Iterate through each entry in the bucket.
				for j := uint64(0); j < bucketCnt; j++ {
					tophash, err := s.peekUint8(bucketAddr + tophashFieldOffset + j)
					if err != nil {
						return errors.New("reading map: " + err.Error())
					}
					// From runtime/hashmap.go
					const minTopHash = 4
					if tophash < minTopHash {
						continue
					}
					keyAddr := bucketAddr + keysFieldOffset + j*keysStride
					valAddr := bucketAddr + valuesFieldOffset + j*valuesStride
					if !fn(keyAddr, valAddr, keyType, valueType) {
						return nil
					}
				}
				var err error
				bucketAddr, err = s.peekPtr(bucketAddr + overflowFieldOffset)
				if err != nil {
					return errors.New("reading map: " + err.Error())
				}
			}
		}
	}

	return nil
}

// peekMapLength returns the number of elements in a map at the given address.
func (s *Server) peekMapLength(t *dwarf.MapType, a uint64) (uint64, error) {
	a, st, err := s.peekMapLocationAndType(t, a)
	if err != nil {
		return 0, err
	}
	if a == 0 {
		// The pointer was nil, so the map is empty.
		return 0, nil
	}
	length, err := s.peekUintOrIntStructField(st, a, "count")
	if err != nil {
		return 0, fmt.Errorf("reading map: %s", err)
	}
	return uint64(length), nil
}
