// Copyright 2009 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 ogle

import (
	"debug/proc"
	"exp/eval"
	"reflect"
)

// This file contains remote runtime definitions.  Using reflection,
// we convert all of these to interpreter types and layout their
// remote representations using the architecture rules.
//
// We could get most of these definitions from our own runtime
// package; however, some of them differ in convenient ways, some of
// them are not defined or exported by the runtime, and having our own
// definitions makes it easy to support multiple remote runtime
// versions.  This may turn out to be overkill.
//
// All of these structures are prefixed with rt1 to indicate the
// runtime version and to mark them as types used only as templates
// for remote types.

/*
 * Runtime data headers
 *
 * See $GOROOT/src/pkg/runtime/runtime.h
 */

type rt1String struct {
	str uintptr
	len int
}

type rt1Slice struct {
	array uintptr
	len   int
	cap   int
}

type rt1Eface struct {
	typ uintptr
	ptr uintptr
}

/*
 * Runtime type structures
 *
 * See $GOROOT/src/pkg/runtime/type.h and $GOROOT/src/pkg/runtime/type.go
 */

type rt1UncommonType struct {
	name    *string
	pkgPath *string
	//methods []method;
}

type rt1CommonType struct {
	size                   uintptr
	hash                   uint32
	alg, align, fieldAlign uint8
	string                 *string
	uncommonType           *rt1UncommonType
}

type rt1Type struct {
	// While Type is technically an Eface, treating the
	// discriminator as an opaque pointer and taking advantage of
	// the commonType prologue on all Type's makes type parsing
	// much simpler.
	typ uintptr
	ptr *rt1CommonType
}

type rt1StructField struct {
	name    *string
	pkgPath *string
	typ     *rt1Type
	tag     *string
	offset  uintptr
}

type rt1StructType struct {
	rt1CommonType
	fields []rt1StructField
}

type rt1PtrType struct {
	rt1CommonType
	elem *rt1Type
}

type rt1SliceType struct {
	rt1CommonType
	elem *rt1Type
}

type rt1ArrayType struct {
	rt1CommonType
	elem *rt1Type
	len  uintptr
}

/*
 * Runtime scheduler structures
 *
 * See $GOROOT/src/pkg/runtime/runtime.h
 */

// Fields beginning with _ are only for padding

type rt1Stktop struct {
	stackguard uintptr
	stackbase  *rt1Stktop
	gobuf      rt1Gobuf
	_args      uint32
	_fp        uintptr
}

type rt1Gobuf struct {
	sp uintptr
	pc uintptr
	g  *rt1G
	r0 uintptr
}

type rt1G struct {
	_stackguard uintptr
	stackbase   *rt1Stktop
	_defer      uintptr
	sched       rt1Gobuf
	_stack0     uintptr
	_entry      uintptr
	alllink     *rt1G
	_param      uintptr
	status      int16
	// Incomplete
}

var rt1GStatus = runtimeGStatus{
	Gidle: 0,
	Grunnable: 1,
	Grunning: 2,
	Gsyscall: 3,
	Gwaiting: 4,
	Gmoribund: 5,
	Gdead: 6,
}

// runtimeIndexes stores the indexes of fields in the runtime
// structures.  It is filled in using reflection, so the name of the
// fields must match the names of the remoteType's in runtimeValues
// exactly and the names of the index fields must be the capitalized
// version of the names of the fields in the runtime structures above.
type runtimeIndexes struct {
	String struct {
		Str, Len int
	}
	Slice struct {
		Array, Len, Cap int
	}
	Eface struct {
		Typ, Ptr int
	}

	UncommonType struct {
		Name, PkgPath int
	}
	CommonType struct {
		Size, Hash, Alg, Align, FieldAlign, String, UncommonType int
	}
	Type struct {
		Typ, Ptr int
	}
	StructField struct {
		Name, PkgPath, Typ, Tag, Offset int
	}
	StructType struct {
		Fields int
	}
	PtrType struct {
		Elem int
	}
	SliceType struct {
		Elem int
	}
	ArrayType struct {
		Elem, Len int
	}

	Stktop struct {
		Stackguard, Stackbase, Gobuf int
	}
	Gobuf struct {
		Sp, Pc, G int
	}
	G struct {
		Stackbase, Sched, Status, Alllink int
	}
}

// Values of G status codes
type runtimeGStatus struct {
	Gidle, Grunnable, Grunning, Gsyscall, Gwaiting, Gmoribund, Gdead int64
}

// runtimeValues stores the types and values that correspond to those
// in the remote runtime package.
type runtimeValues struct {
	// Runtime data headers
	String, Slice, Eface *remoteType
	// Runtime type structures
	Type, CommonType, UncommonType, StructField, StructType, PtrType,
		ArrayType, SliceType *remoteType
	// Runtime scheduler structures
	Stktop, Gobuf, G *remoteType
	// Addresses of *runtime.XType types.  These are the
	// discriminators on the runtime.Type interface.  We use local
	// reflection to fill these in from the remote symbol table,
	// so the names must match the runtime names.
	PBoolType,
		PUint8Type, PUint16Type, PUint32Type, PUint64Type, PUintType, PUintptrType,
		PInt8Type, PInt16Type, PInt32Type, PInt64Type, PIntType,
		PFloat32Type, PFloat64Type, PFloatType,
		PArrayType, PStringType, PStructType, PPtrType, PFuncType,
		PInterfaceType, PSliceType, PMapType, PChanType,
		PDotDotDotType, PUnsafePointerType proc.Word
	// G status values
	runtimeGStatus
}

// fillRuntimeIndexes fills a runtimeIndexes structure will the field
// indexes gathered from the remoteTypes recorded in a runtimeValues
// structure.
func fillRuntimeIndexes(runtime *runtimeValues, out *runtimeIndexes) {
	outv := reflect.Indirect(reflect.NewValue(out)).(*reflect.StructValue)
	outt := outv.Type().(*reflect.StructType)
	runtimev := reflect.Indirect(reflect.NewValue(runtime)).(*reflect.StructValue)

	// out contains fields corresponding to each runtime type
	for i := 0; i < outt.NumField(); i++ {
		// Find the interpreter type for this runtime type
		name := outt.Field(i).Name
		et := runtimev.FieldByName(name).Interface().(*remoteType).Type.(*eval.StructType)

		// Get the field indexes of the interpreter struct type
		indexes := make(map[string]int, len(et.Elems))
		for j, f := range et.Elems {
			if f.Anonymous {
				continue
			}
			name := f.Name
			if name[0] >= 'a' && name[0] <= 'z' {
				name = string(name[0]+'A'-'a') + name[1:]
			}
			indexes[name] = j
		}

		// Fill this field of out
		outStructv := outv.Field(i).(*reflect.StructValue)
		outStructt := outStructv.Type().(*reflect.StructType)
		for j := 0; j < outStructt.NumField(); j++ {
			f := outStructv.Field(j).(*reflect.IntValue)
			name := outStructt.Field(j).Name
			f.Set(indexes[name])
		}
	}
}
