// Copyright 2018 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package state

import (
	"bytes"
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"reflect"
	"sort"

	"github.com/golang/protobuf/proto"
	pb "gvisor.dev/gvisor/pkg/state/object_go_proto"
)

// objectState represents an object that may be in the process of being
// decoded. Specifically, it represents either a decoded object, or an an
// interest in a future object that will be decoded. When that interest is
// registered (via register), the storage for the object will be created, but
// it will not be decoded until the object is encountered in the stream.
type objectState struct {
	// id is the id for this object.
	//
	// If this field is zero, then this is an anonymous (unregistered,
	// non-reference primitive) object. This is immutable.
	id uint64

	// obj is the object. This may or may not be valid yet, depending on
	// whether complete returns true. However, regardless of whether the
	// object is valid, obj contains a final storage location for the
	// object. This is immutable.
	//
	// Note that this must be addressable (obj.Addr() must not panic).
	//
	// The obj passed to the decode methods below will equal this obj only
	// in the case of decoding the top-level object. However, the passed
	// obj may represent individual fields, elements of a slice, etc. that
	// are effectively embedded within the reflect.Value below but with
	// distinct types.
	obj reflect.Value

	// blockedBy is the number of dependencies this object has.
	blockedBy int

	// blocking is a list of the objects blocked by this one.
	blocking []*objectState

	// callbacks is a set of callbacks to execute on load.
	callbacks []func()

	// path is the decoding path to the object.
	path recoverable
}

// complete indicates the object is complete.
func (os *objectState) complete() bool {
	return os.blockedBy == 0 && len(os.callbacks) == 0
}

// checkComplete checks for completion. If the object is complete, pending
// callbacks will be executed and checkComplete will be called on downstream
// objects (those depending on this one).
func (os *objectState) checkComplete(stats *Stats) {
	if os.blockedBy > 0 {
		return
	}
	stats.Start(os.obj)

	// Fire all callbacks.
	for _, fn := range os.callbacks {
		fn()
	}
	os.callbacks = nil

	// Clear all blocked objects.
	for _, other := range os.blocking {
		other.blockedBy--
		other.checkComplete(stats)
	}
	os.blocking = nil
	stats.Done()
}

// waitFor queues a dependency on the given object.
func (os *objectState) waitFor(other *objectState, callback func()) {
	os.blockedBy++
	other.blocking = append(other.blocking, os)
	if callback != nil {
		other.callbacks = append(other.callbacks, callback)
	}
}

// findCycleFor returns when the given object is found in the blocking set.
func (os *objectState) findCycleFor(target *objectState) []*objectState {
	for _, other := range os.blocking {
		if other == target {
			return []*objectState{target}
		} else if childList := other.findCycleFor(target); childList != nil {
			return append(childList, other)
		}
	}
	return nil
}

// findCycle finds a dependency cycle.
func (os *objectState) findCycle() []*objectState {
	return append(os.findCycleFor(os), os)
}

// decodeState is a graph of objects in the process of being decoded.
//
// The decode process involves loading the breadth-first graph generated by
// encode. This graph is read in it's entirety, ensuring that all object
// storage is complete.
//
// As the graph is being serialized, a set of completion callbacks are
// executed. These completion callbacks should form a set of acyclic subgraphs
// over the original one. After decoding is complete, the objects are scanned
// to ensure that all callbacks are executed, otherwise the callback graph was
// not acyclic.
type decodeState struct {
	// ctx is the decode context.
	ctx context.Context

	// objectByID is the set of objects in progress.
	objectsByID map[uint64]*objectState

	// deferred are objects that have been read, by no interest has been
	// registered yet. These will be decoded once interest in registered.
	deferred map[uint64]*pb.Object

	// outstanding is the number of outstanding objects.
	outstanding uint32

	// r is the input stream.
	r io.Reader

	// stats is the passed stats object.
	stats *Stats

	// recoverable is the panic recover facility.
	recoverable
}

// lookup looks up an object in decodeState or returns nil if no such object
// has been previously registered.
func (ds *decodeState) lookup(id uint64) *objectState {
	return ds.objectsByID[id]
}

// wait registers a dependency on an object.
//
// As a special case, we always allow _useable_ references back to the first
// decoding object because it may have fields that are already decoded. We also
// allow trivial self reference, since they can be handled internally.
func (ds *decodeState) wait(waiter *objectState, id uint64, callback func()) {
	switch id {
	case 0:
		// Nil pointer; nothing to wait for.
		fallthrough
	case waiter.id:
		// Trivial self reference.
		fallthrough
	case 1:
		// Root object; see above.
		if callback != nil {
			callback()
		}
		return
	}

	// No nil can be returned here.
	waiter.waitFor(ds.lookup(id), callback)
}

// waitObject notes a blocking relationship.
func (ds *decodeState) waitObject(os *objectState, p *pb.Object, callback func()) {
	if rv, ok := p.Value.(*pb.Object_RefValue); ok {
		// Refs can encode pointers and maps.
		ds.wait(os, rv.RefValue, callback)
	} else if sv, ok := p.Value.(*pb.Object_SliceValue); ok {
		// See decodeObject; we need to wait for the array (if non-nil).
		ds.wait(os, sv.SliceValue.RefValue, callback)
	} else if iv, ok := p.Value.(*pb.Object_InterfaceValue); ok {
		// It's an interface (wait recurisvely).
		ds.waitObject(os, iv.InterfaceValue.Value, callback)
	} else if callback != nil {
		// Nothing to wait for: execute the callback immediately.
		callback()
	}
}

// register registers a decode with a type.
//
// This type is only used to instantiate a new object if it has not been
// registered previously.
func (ds *decodeState) register(id uint64, typ reflect.Type) *objectState {
	os, ok := ds.objectsByID[id]
	if ok {
		return os
	}

	// Record in the object index.
	if typ.Kind() == reflect.Map {
		os = &objectState{id: id, obj: reflect.MakeMap(typ), path: ds.recoverable.copy()}
	} else {
		os = &objectState{id: id, obj: reflect.New(typ).Elem(), path: ds.recoverable.copy()}
	}
	ds.objectsByID[id] = os

	if o, ok := ds.deferred[id]; ok {
		// There is a deferred object.
		delete(ds.deferred, id) // Free memory.
		ds.decodeObject(os, os.obj, o, "", nil)
	} else {
		// There is no deferred object.
		ds.outstanding++
	}

	return os
}

// decodeStruct decodes a struct value.
func (ds *decodeState) decodeStruct(os *objectState, obj reflect.Value, s *pb.Struct) {
	// Set the fields.
	m := Map{newInternalMap(nil, ds, os)}
	defer internalMapPool.Put(m.internalMap)
	for _, field := range s.Fields {
		m.data = append(m.data, entry{
			name:   field.Name,
			object: field.Value,
		})
	}

	// Sort the fields for efficient searching.
	//
	// Technically, these should already appear in sorted order in the
	// state ordering, so this cost is effectively a single scan to ensure
	// that the order is correct.
	if len(m.data) > 1 {
		sort.Slice(m.data, func(i, j int) bool {
			return m.data[i].name < m.data[j].name
		})
	}

	// Invoke the load; this will recursively decode other objects.
	fns, ok := registeredTypes.lookupFns(obj.Addr().Type())
	if ok {
		// Invoke the loader.
		fns.invokeLoad(obj.Addr(), m)
	} else if obj.NumField() == 0 {
		// Allow anonymous empty structs.
		return
	} else {
		// Propagate an error.
		panic(fmt.Errorf("unregistered type %s", obj.Type()))
	}
}

// decodeMap decodes a map value.
func (ds *decodeState) decodeMap(os *objectState, obj reflect.Value, m *pb.Map) {
	if obj.IsNil() {
		obj.Set(reflect.MakeMap(obj.Type()))
	}
	for i := 0; i < len(m.Keys); i++ {
		// Decode the objects.
		kv := reflect.New(obj.Type().Key()).Elem()
		vv := reflect.New(obj.Type().Elem()).Elem()
		ds.decodeObject(os, kv, m.Keys[i], ".(key %d)", i)
		ds.decodeObject(os, vv, m.Values[i], "[%#v]", kv.Interface())
		ds.waitObject(os, m.Keys[i], nil)
		ds.waitObject(os, m.Values[i], nil)

		// Set in the map.
		obj.SetMapIndex(kv, vv)
	}
}

// decodeArray decodes an array value.
func (ds *decodeState) decodeArray(os *objectState, obj reflect.Value, a *pb.Array) {
	if len(a.Contents) != obj.Len() {
		panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", obj.Len(), len(a.Contents)))
	}
	// Decode the contents into the array.
	for i := 0; i < len(a.Contents); i++ {
		ds.decodeObject(os, obj.Index(i), a.Contents[i], "[%d]", i)
		ds.waitObject(os, a.Contents[i], nil)
	}
}

// decodeInterface decodes an interface value.
func (ds *decodeState) decodeInterface(os *objectState, obj reflect.Value, i *pb.Interface) {
	// Is this a nil value?
	if i.Type == "" {
		return // Just leave obj alone.
	}

	// Get the dispatchable type. This may not be used if the given
	// reference has already been resolved, but if not we need to know the
	// type to create.
	t, ok := registeredTypes.lookupType(i.Type)
	if !ok {
		panic(fmt.Errorf("no valid type for %q", i.Type))
	}

	if obj.Kind() != reflect.Map {
		// Set the obj to be the given typed value; this actually sets
		// obj to be a non-zero value -- namely, it inserts type
		// information. There's no need to do this for maps.
		obj.Set(reflect.Zero(t))
	}

	// Decode the dereferenced element; there is no need to wait here, as
	// the interface object shares the current object state.
	ds.decodeObject(os, obj, i.Value, ".(%s)", i.Type)
}

// decodeObject decodes a object value.
func (ds *decodeState) decodeObject(os *objectState, obj reflect.Value, object *pb.Object, format string, param interface{}) {
	ds.push(false, format, param)
	ds.stats.Add(obj)
	ds.stats.Start(obj)

	switch x := object.GetValue().(type) {
	case *pb.Object_BoolValue:
		obj.SetBool(x.BoolValue)
	case *pb.Object_StringValue:
		obj.SetString(string(x.StringValue))
	case *pb.Object_Int64Value:
		obj.SetInt(x.Int64Value)
		if obj.Int() != x.Int64Value {
			panic(fmt.Errorf("signed integer truncated in %v for %s", object, obj.Type()))
		}
	case *pb.Object_Uint64Value:
		obj.SetUint(x.Uint64Value)
		if obj.Uint() != x.Uint64Value {
			panic(fmt.Errorf("unsigned integer truncated in %v for %s", object, obj.Type()))
		}
	case *pb.Object_DoubleValue:
		obj.SetFloat(x.DoubleValue)
		if obj.Float() != x.DoubleValue {
			panic(fmt.Errorf("float truncated in %v for %s", object, obj.Type()))
		}
	case *pb.Object_RefValue:
		// Resolve the pointer itself, even though the object may not
		// be decoded yet. You need to use wait() in order to ensure
		// that is the case. See wait above, and Map.Barrier.
		if id := x.RefValue; id != 0 {
			// Decoding the interface should have imparted type
			// information, so from this point it's safe to resolve
			// and use this dynamic information for actually
			// creating the object in register.
			//
			// (For non-interfaces this is a no-op).
			dyntyp := reflect.TypeOf(obj.Interface())
			if dyntyp.Kind() == reflect.Map {
				// Remove the map object count here to avoid
				// double counting, as this object will be
				// counted again when it gets processed later.
				// We do not add a reference count as the
				// reference is artificial.
				ds.stats.Remove(obj)
				obj.Set(ds.register(id, dyntyp).obj)
			} else if dyntyp.Kind() == reflect.Ptr {
				ds.push(true /* dereference */, "", nil)
				obj.Set(ds.register(id, dyntyp.Elem()).obj.Addr())
				ds.pop()
			} else {
				obj.Set(ds.register(id, dyntyp.Elem()).obj.Addr())
			}
		} else {
			// We leave obj alone here. That's because if obj
			// represents an interface, it may have been embued
			// with type information in decodeInterface, and we
			// don't want to destroy that information.
		}
	case *pb.Object_SliceValue:
		// It's okay to slice the array here, since the contents will
		// still be provided later on. These semantics are a bit
		// strange but they are handled in the Map.Barrier properly.
		//
		// The special semantics of zero ref apply here too.
		if id := x.SliceValue.RefValue; id != 0 && x.SliceValue.Capacity > 0 {
			v := reflect.ArrayOf(int(x.SliceValue.Capacity), obj.Type().Elem())
			obj.Set(ds.register(id, v).obj.Slice3(0, int(x.SliceValue.Length), int(x.SliceValue.Capacity)))
		}
	case *pb.Object_ArrayValue:
		ds.decodeArray(os, obj, x.ArrayValue)
	case *pb.Object_StructValue:
		ds.decodeStruct(os, obj, x.StructValue)
	case *pb.Object_MapValue:
		ds.decodeMap(os, obj, x.MapValue)
	case *pb.Object_InterfaceValue:
		ds.decodeInterface(os, obj, x.InterfaceValue)
	case *pb.Object_ByteArrayValue:
		copyArray(obj, reflect.ValueOf(x.ByteArrayValue))
	case *pb.Object_Uint16ArrayValue:
		// 16-bit slices are serialized as 32-bit slices.
		// See object.proto for details.
		s := x.Uint16ArrayValue.Values
		t := obj.Slice(0, obj.Len()).Interface().([]uint16)
		if len(t) != len(s) {
			panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", len(t), len(s)))
		}
		for i := range s {
			t[i] = uint16(s[i])
		}
	case *pb.Object_Uint32ArrayValue:
		copyArray(obj, reflect.ValueOf(x.Uint32ArrayValue.Values))
	case *pb.Object_Uint64ArrayValue:
		copyArray(obj, reflect.ValueOf(x.Uint64ArrayValue.Values))
	case *pb.Object_UintptrArrayValue:
		copyArray(obj, castSlice(reflect.ValueOf(x.UintptrArrayValue.Values), reflect.TypeOf(uintptr(0))))
	case *pb.Object_Int8ArrayValue:
		copyArray(obj, castSlice(reflect.ValueOf(x.Int8ArrayValue.Values), reflect.TypeOf(int8(0))))
	case *pb.Object_Int16ArrayValue:
		// 16-bit slices are serialized as 32-bit slices.
		// See object.proto for details.
		s := x.Int16ArrayValue.Values
		t := obj.Slice(0, obj.Len()).Interface().([]int16)
		if len(t) != len(s) {
			panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", len(t), len(s)))
		}
		for i := range s {
			t[i] = int16(s[i])
		}
	case *pb.Object_Int32ArrayValue:
		copyArray(obj, reflect.ValueOf(x.Int32ArrayValue.Values))
	case *pb.Object_Int64ArrayValue:
		copyArray(obj, reflect.ValueOf(x.Int64ArrayValue.Values))
	case *pb.Object_BoolArrayValue:
		copyArray(obj, reflect.ValueOf(x.BoolArrayValue.Values))
	case *pb.Object_Float64ArrayValue:
		copyArray(obj, reflect.ValueOf(x.Float64ArrayValue.Values))
	case *pb.Object_Float32ArrayValue:
		copyArray(obj, reflect.ValueOf(x.Float32ArrayValue.Values))
	default:
		// Shoud not happen, not propagated as an error.
		panic(fmt.Sprintf("unknown object %v for %s", object, obj.Type()))
	}

	ds.stats.Done()
	ds.pop()
}

func copyArray(dest reflect.Value, src reflect.Value) {
	if dest.Len() != src.Len() {
		panic(fmt.Errorf("mismatching array length expect=%d, actual=%d", dest.Len(), src.Len()))
	}
	reflect.Copy(dest, castSlice(src, dest.Type().Elem()))
}

// Deserialize deserializes the object state.
//
// This function may panic and should be run in safely().
func (ds *decodeState) Deserialize(obj reflect.Value) {
	ds.objectsByID[1] = &objectState{id: 1, obj: obj, path: ds.recoverable.copy()}
	ds.outstanding = 1 // The root object.

	// Decode all objects in the stream.
	//
	// See above, we never process objects while we have no outstanding
	// interests (other than the very first object).
	for id := uint64(1); ds.outstanding > 0; id++ {
		os := ds.lookup(id)
		ds.stats.Start(os.obj)

		o, err := ds.readObject()
		if err != nil {
			panic(err)
		}

		if os != nil {
			// Decode the object.
			ds.from = &os.path
			ds.decodeObject(os, os.obj, o, "", nil)
			ds.outstanding--
		} else {
			// If an object hasn't had interest registered
			// previously, we deferred decoding until interest is
			// registered.
			ds.deferred[id] = o
		}

		ds.stats.Done()
	}

	// Check the zero-length header at the end.
	length, object, err := ReadHeader(ds.r)
	if err != nil {
		panic(err)
	}
	if length != 0 {
		panic(fmt.Sprintf("expected zero-length terminal, got %d", length))
	}
	if object {
		panic("expected non-object terminal")
	}

	// Check if we have any deferred objects.
	if count := len(ds.deferred); count > 0 {
		// Shoud not happen, not propagated as an error.
		panic(fmt.Sprintf("still have %d deferred objects", count))
	}

	// Scan and fire all callbacks.
	for _, os := range ds.objectsByID {
		os.checkComplete(ds.stats)
	}

	// Check if we have any remaining dependency cycles.
	for _, os := range ds.objectsByID {
		if !os.complete() {
			// This must be the result of a dependency cycle.
			cycle := os.findCycle()
			var buf bytes.Buffer
			buf.WriteString("dependency cycle: {")
			for i, cycleOS := range cycle {
				if i > 0 {
					buf.WriteString(" => ")
				}
				buf.WriteString(fmt.Sprintf("%s", cycleOS.obj.Type()))
			}
			buf.WriteString("}")
			// Panic as an error; propagate to the caller.
			panic(errors.New(string(buf.Bytes())))
		}
	}
}

type byteReader struct {
	io.Reader
}

// ReadByte implements io.ByteReader.
func (br byteReader) ReadByte() (byte, error) {
	var b [1]byte
	n, err := br.Reader.Read(b[:])
	if n > 0 {
		return b[0], nil
	} else if err != nil {
		return 0, err
	} else {
		return 0, io.ErrUnexpectedEOF
	}
}

// ReadHeader reads an object header.
//
// Each object written to the statefile is prefixed with a header. See
// WriteHeader for more information; these functions are exported to allow
// non-state writes to the file to play nice with debugging tools.
func ReadHeader(r io.Reader) (length uint64, object bool, err error) {
	// Read the header.
	length, err = binary.ReadUvarint(byteReader{r})
	if err != nil {
		return
	}

	// Decode whether the object is valid.
	object = length&0x1 != 0
	length = length >> 1
	return
}

// readObject reads an object from the stream.
func (ds *decodeState) readObject() (*pb.Object, error) {
	// Read the header.
	length, object, err := ReadHeader(ds.r)
	if err != nil {
		return nil, err
	}
	if !object {
		return nil, fmt.Errorf("invalid object header")
	}

	// Read the object.
	buf := make([]byte, length)
	for done := 0; done < len(buf); {
		n, err := ds.r.Read(buf[done:])
		done += n
		if n == 0 && err != nil {
			return nil, err
		}
	}

	// Unmarshal.
	obj := new(pb.Object)
	if err := proto.Unmarshal(buf, obj); err != nil {
		return nil, err
	}

	return obj, nil
}
