// Copyright 2016 The Vanadium 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 vdl

import (
	"errors"
	"fmt"
	"math"
	"reflect"
	"sync"
)

var (
	errEmptyPipeStack        = errors.New("vdl: empty pipe stack")
	errEncCallDuringDecPhase = errors.New("vdl: pipe encoder method called during decode phase")
	errInvalidPipeState      = errors.New("vdl: invalid pipe state")
)

func convertPipe(dst, src interface{}) error {
	enc, dec := newPipe()
	go func() {
		enc.Close(Write(enc, src))
	}()
	return dec.Close(Read(dec, dst))
}

func convertPipeReflect(dst, src reflect.Value) error {
	enc, dec := newPipe()
	go func() {
		enc.Close(WriteReflect(enc, src))
	}()
	return dec.Close(ReadReflect(dec, dst))
}

// newPipe returns a pipeEncoder and pipeDecoder connected via the same "pipe".
// Conceptually this is similar to an os.Pipe between a io.Writer and io.Reader.
// It is used to pair together vdl.Write and vdl.Read calls during conversion.
//
// Note that vdl.Write calls a sequence of pipeEncoder methods, while vdl.Read
// calls a sequence of pipeDecoder methods.  The concept behind the pipe is that
// we match each {Start,Finish}Value on the pipeEncoder with a corresponding
// call on the pipeDecoder.  Only one call is allowed to be in-flight at a time.
//
// We bootstrap with the first enc.StartValue call.  After this first call,
// every subsequent call to enc.{Start,Finish}Value blocks, waiting for the
// previous call to be matched by a call on the decoder.  Similarly every call
// to dec.{Start,Finish}Value blocks, waiting to match the encoder call.
// Control alternates between the Encoder and Decoder until completion.
//
// The Close method shuts the pipe down, causing everything to unblock.
func newPipe() (*pipeEncoder, *pipeDecoder) {
	d := &pipeDecoder{Enc: pipeEncoder{}}
	d.Enc.Cond.L = &d.Enc.Mutex
	return &d.Enc, d
}

type pipeEncoder struct {
	sync.Mutex
	Cond sync.Cond

	Stack                    []pipeStackEntry
	NextEntryDone            bool
	NextFieldName            string
	NextStartValueIsOptional bool       // The StartValue refers to an optional type.
	NumberType               numberType // The number type X in EncodeX.

	// EncIsBytes, DecBytesAsEntries and DecByteStartValue deal with a subtlety
	// when handling bytes.  Normally the {Start,Finish}Value calls on the Encoder
	// are perfectly matched by the same calls on the Decoder; the pipe's blocking
	// mechanism depends on this.  But since we allow value conversions, it's
	// valid for the following mismatched sequences to occur:
	//    # Encode bytes, decode as an array or list
	//    Encoder: StartValue,EncodeBytes,                           FinishValue
	//    Decoder: StartValue,(NextEntry,StartValue,FinishValue,...),FinishValue
	//
	//    # Encode array or list, decode as bytes
	//    Encoder: StartValue,(NextEntry,StartValue,FinishValue,...),FinishValue
	//    Decoder: StartValue,DecodeBytes,                           FinishValue
	//
	// EncIsBytes is set in enc.EncodeBytes, and cleared in enc.FinishValue.
	// DecBytesAsEntries is set in dec.NextEntry, and cleared in dec.FinishValue.
	// DecByteStartValue is set in dec.StartValue, and cleared in dec.FinishValue.
	// The concept is EncIsBytes tracks the encoder bytes state.  If it is set,
	// and dec.NextEntry is called, it means the caller is decoding the bytes as a
	// sequence of entries.  Thereafter pairs of dec.{Start,FinishValue} calls are
	// allowed to proceed without blocking.  The final dec.FinishValue resumes the
	// regular pattern of blocking on matching calls.
	EncIsBytes        bool
	DecBytesAsEntries bool
	DecByteStartValue bool

	DecStarted bool // Decoding has started
	Err        error

	State pipeState

	// Arguments from Encode* to be passed to Decode*:
	ArgBool   bool
	ArgUint   uint64
	ArgInt    int64
	ArgFloat  float64
	ArgString string
	ArgBytes  []byte
	ArgType   *Type
}

type pipeStackEntry struct {
	Type       *Type
	NextOp     pipeOp
	LenHint    int
	Index      int
	NumStarted int
	IsOptional bool
	IsNil      bool
}

type pipeDecoder struct {
	Enc                  pipeEncoder
	ignoreNextStartValue bool
}

// pipeState represents the blocking state of the pipe.  Control is transferred
// alternately between the encoder and decoder; while one side is running, the
// other side blocks.  Once the closed state is entered, everything unblocks.
type pipeState int

const (
	pipeStateEncoder pipeState = iota
	pipeStateDecoder
	pipeStateClosed
)

func (x pipeState) String() string {
	switch x {
	case pipeStateEncoder:
		return "Encoder"
	case pipeStateDecoder:
		return "Decoder"
	case pipeStateClosed:
		return "Closed"
	default:
		panic(fmt.Errorf("vdl: unknown pipeState %d", x))
	}
}

// pipeOp is used to check our invariants for state transitions.
type pipeOp int

const (
	pipeStartEnc pipeOp = iota
	pipeStartDec
	pipeFinishEnc
	pipeFinishDec
)

func (op pipeOp) String() string {
	switch op {
	case pipeStartEnc:
		return "StartEnc"
	case pipeStartDec:
		return "StartDec"
	case pipeFinishEnc:
		return "FinishEnc"
	case pipeFinishDec:
		return "FinishDec"
	default:
		panic("bad op")
	}
}

func (op pipeOp) Next() pipeOp {
	if op == pipeFinishDec {
		op = pipeStartEnc
	} else {
		op++
	}
	return op
}

// We can only determine whether the next value is AnyType
// by checking the next type of the entry.
func (entry *pipeStackEntry) nextValueIsAny() bool {
	switch entry.Type.Kind() {
	case List, Array:
		return entry.Type.Elem() == AnyType
	case Set:
		return entry.Type.Key() == AnyType
	case Map:
		switch entry.NumStarted % 2 {
		case 1:
			return entry.Type.Key() == AnyType
		case 0:
			return entry.Type.Elem() == AnyType
		}
	case Struct, Union:
		return entry.Type.Field(entry.Index).Type == AnyType
	}
	return false
}

type numberType int

const (
	numberUint numberType = iota
	numberInt
	numberFloat
)

func (e *pipeEncoder) top() *pipeStackEntry {
	if len(e.Stack) == 0 {
		return nil
	}
	return &e.Stack[len(e.Stack)-1]
}

func (d *pipeDecoder) top() *pipeStackEntry {
	if len(d.Enc.Stack) == 0 {
		return nil
	}
	return &d.Enc.Stack[len(d.Enc.Stack)-1]
}

func (d *pipeDecoder) Lock()   { d.Enc.Mutex.Lock() }
func (d *pipeDecoder) Unlock() { d.Enc.Mutex.Unlock() }

func (e *pipeEncoder) closeLocked(err error) error {
	if err != nil && e.Err == nil {
		e.Err = err
	}
	e.State = pipeStateClosed
	e.Cond.Broadcast()
	return e.Err
}

func (e *pipeEncoder) Close(err error) error {
	e.Lock()
	defer e.Unlock()
	return e.closeLocked(err)
}

func (d *pipeDecoder) Close(err error) error {
	return d.Enc.Close(err)
}

func (e *pipeEncoder) SetNextStartValueIsOptional() {
	e.NextStartValueIsOptional = true
}

func (e *pipeEncoder) NilValue(tt *Type) error {
	switch tt.Kind() {
	case Any:
	case Optional:
		e.SetNextStartValueIsOptional()
	default:
		return fmt.Errorf("concrete types disallowed for NilValue (type was %v)", tt)
	}
	if err := e.StartValue(tt); err != nil {
		return err
	}
	top := e.top()
	if top == nil {
		return e.Close(errEmptyPipeStack)
	}
	top.IsNil = true
	return e.FinishValue()
}

func (e *pipeEncoder) StartValue(tt *Type) error {
	e.Lock()
	defer e.Unlock()
	if e.State != pipeStateEncoder {
		return e.closeLocked(errInvalidPipeState)
	}
	if err := e.wait(); err != nil {
		return err
	}
	top := e.top()
	if top != nil {
		top.NumStarted++
	}
	e.Stack = append(e.Stack, pipeStackEntry{
		Type:       tt,
		NextOp:     pipeStartDec,
		Index:      -1,
		LenHint:    -1,
		IsOptional: e.NextStartValueIsOptional,
	})
	e.NextStartValueIsOptional = false
	return e.Err
}

func (e *pipeEncoder) FinishValue() error {
	e.Lock()
	defer e.Unlock()
	if e.State != pipeStateEncoder {
		return e.closeLocked(errInvalidPipeState)
	}
	if err := e.wait(); err != nil {
		return err
	}
	top := e.top()
	if top == nil {
		return e.closeLocked(errEmptyPipeStack)
	}
	if got, want := top.NextOp, pipeFinishEnc; got != want {
		return e.closeLocked(fmt.Errorf("vdl: pipe got state %v, want %v", got, want))
	}
	top.NextOp = top.NextOp.Next()
	// We're finished with the enc.EncodeBytes special case once we've unblocked,
	// regardless of what sequence of Decoder calls were made.
	e.EncIsBytes = false
	return e.Err
}

func (e *pipeEncoder) wait() error {
	top := e.top()
	if e.State == pipeStateClosed {
		return e.Err
	}
	if top != nil {
		e.State = pipeStateDecoder
		e.Cond.Broadcast()
		for e.State == pipeStateDecoder {
			e.Cond.Wait()
		}
		if e.State == pipeStateClosed {
			return e.Err
		}
	}
	return nil
}

func (d *pipeDecoder) StartValue(want *Type) error {
	d.Lock()
	defer d.Unlock()
	if d.Enc.DecStarted && d.Enc.State != pipeStateDecoder {
		return d.Enc.closeLocked(errInvalidPipeState)
	}
	if d.ignoreNextStartValue {
		d.ignoreNextStartValue = false
		return d.Enc.Err
	}
	// Don't block if enc.EncodeBytes was called, but the caller is decoding as a
	// sequence of entries.  See the matching logic in dec.FinishValue.
	if d.Enc.DecBytesAsEntries {
		if d.Enc.DecByteStartValue {
			return d.Enc.closeLocked(fmt.Errorf("vdl: can't StartValue on byte"))
		}
		d.Enc.DecByteStartValue = true
		return d.Enc.Err
	}
	if err := d.wait(false); err != nil {
		return err
	}
	top := d.top()
	if top == nil {
		return d.Enc.closeLocked(errEmptyPipeStack)
	}
	// Check compatibility between the actual type and the want type.  Since
	// compatibility applies to the entire static type, we only need to perform
	// this check for top-level decoded values, and subsequently for decoded any
	// values.
	if len(d.Enc.Stack) == 1 || d.IsAny() {
		if tt := d.Type(); !Compatible(tt, want) {
			return d.Enc.closeLocked(fmt.Errorf("vdl: pipe incompatible decode from %v into %v", tt, want))
		}
	}
	if got, want := top.NextOp, pipeStartDec; got != want {
		return d.Enc.closeLocked(fmt.Errorf("vdl: pipe got state %v, want %v", got, want))
	}
	top.NextOp = top.NextOp.Next()
	return d.Enc.Err
}

func (d *pipeDecoder) FinishValue() error {
	d.Lock()
	defer d.Unlock()
	switch {
	case d.Enc.State == pipeStateEncoder:
		return d.Enc.closeLocked(errInvalidPipeState)
	case d.Enc.State == pipeStateClosed:
		return d.Enc.Err
	}
	// Don't block if enc.EncodeBytes was called, but the caller is decoding as a
	// sequence of entries.  See the matching logic in dec.StartValue.
	if d.Enc.DecBytesAsEntries {
		if d.Enc.DecByteStartValue {
			d.Enc.DecByteStartValue = false
			return d.Enc.Err
		}
		//
		d.Enc.DecBytesAsEntries = false
	}
	if err := d.wait(true); err != nil {
		return err
	}
	top := d.top()
	if top == nil {
		return d.Enc.closeLocked(errEmptyPipeStack)
	}
	if got, want := top.NextOp, pipeFinishDec; got != want {
		return d.Enc.closeLocked(fmt.Errorf("vdl: pipe got state %v, want %v", got, want))
	}
	d.Enc.Stack = d.Enc.Stack[:len(d.Enc.Stack)-1]
	return d.Enc.Err
}

func (d *pipeDecoder) wait(isFinish bool) error {
	if d.Enc.State == pipeStateClosed {
		return d.Enc.Err
	}
	if isFinish || d.Enc.DecStarted {
		d.Enc.State = pipeStateEncoder
		d.Enc.Cond.Broadcast()
	}
	d.Enc.DecStarted = true
	for d.Enc.State == pipeStateEncoder {
		d.Enc.Cond.Wait()
	}
	if d.Enc.State == pipeStateClosed {
		return d.Enc.Err
	}
	return nil
}

func (d *pipeDecoder) SkipValue() error {
	if err := d.StartValue(AnyType); err != nil {
		return err
	}
	return d.FinishValue()
}

func (d *pipeDecoder) IgnoreNextStartValue() {
	d.ignoreNextStartValue = true
}

func (e *pipeEncoder) SetLenHint(lenHint int) error {
	top := e.top()
	if top == nil {
		return e.Close(errEmptyPipeStack)
	}
	top.LenHint = lenHint
	return e.Err
}

func (e *pipeEncoder) NextEntry(done bool) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.NextEntryDone = done
	return e.Err
}
func (e *pipeEncoder) NextField(name string) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.NextFieldName = name
	return e.Err
}

func (d *pipeDecoder) NextEntry() (bool, error) {
	top := d.top()
	if top == nil {
		return false, d.Close(errEmptyPipeStack)
	}
	top.Index++
	var done bool
	if d.Enc.EncIsBytes {
		d.Enc.DecBytesAsEntries = true
		done = top.Index >= len(d.Enc.ArgBytes)
	} else {
		done = d.Enc.NextEntryDone
	}
	d.Enc.NextEntryDone = false
	return done, d.Enc.Err
}

func (d *pipeDecoder) NextField() (string, error) {
	top := d.top()
	if top == nil {
		return "", d.Close(errEmptyPipeStack)
	}
	top.Index++
	name := d.Enc.NextFieldName
	d.Enc.NextFieldName = ""
	return name, d.Enc.Err
}

func (d *pipeDecoder) Type() *Type {
	top := d.top()
	if top == nil {
		return nil
	}
	if d.Enc.DecBytesAsEntries {
		return top.Type.Elem()
	}
	return top.Type
}

func (d *pipeDecoder) IsAny() bool {
	if stackTop2 := len(d.Enc.Stack) - 2; stackTop2 >= 0 {
		return d.Enc.Stack[stackTop2].nextValueIsAny()
	}
	return false
}

func (d *pipeDecoder) IsOptional() bool {
	if top := d.top(); top != nil {
		return top.IsOptional
	}
	return false
}

func (d *pipeDecoder) IsNil() bool {
	if top := d.top(); top != nil {
		return top.IsNil
	}
	return false
}

func (d *pipeDecoder) Index() int {
	if top := d.top(); top != nil {
		return top.Index
	}
	return -1
}

func (d *pipeDecoder) LenHint() int {
	if top := d.top(); top != nil {
		return top.LenHint
	}
	return -1
}

func (e *pipeEncoder) EncodeBool(v bool) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.ArgBool = v
	return e.Err
}

func (d *pipeDecoder) DecodeBool() (bool, error) {
	return d.Enc.ArgBool, d.Enc.Err
}

func (e *pipeEncoder) EncodeString(v string) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.ArgString = v
	return e.Err
}

func (d *pipeDecoder) DecodeString() (string, error) {
	return d.Enc.ArgString, d.Enc.Err
}

func (e *pipeEncoder) EncodeTypeObject(v *Type) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.ArgType = v
	return e.Err
}

func (d *pipeDecoder) DecodeTypeObject() (*Type, error) {
	return d.Enc.ArgType, d.Enc.Err
}

func (e *pipeEncoder) EncodeUint(v uint64) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.ArgUint = v
	e.NumberType = numberUint
	return e.Err
}

func (d *pipeDecoder) DecodeUint(bitlen int) (uint64, error) {
	const errFmt = "vdl: conversion from %v into uint%d loses precision: %v"
	top, tt := d.top(), d.Type()
	if top == nil {
		return 0, d.Close(errEmptyPipeStack)
	}
	switch d.Enc.NumberType {
	case numberUint:
		x := d.Enc.ArgUint
		if d.Enc.DecBytesAsEntries {
			x = uint64(d.Enc.ArgBytes[top.Index])
		}
		if shift := 64 - uint(bitlen); x != (x<<shift)>>shift {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return x, d.Enc.Err
	case numberInt:
		x := d.Enc.ArgInt
		ux := uint64(x)
		if shift := 64 - uint(bitlen); x < 0 || ux != (ux<<shift)>>shift {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return ux, d.Enc.Err
	case numberFloat:
		x := d.Enc.ArgFloat
		ux := uint64(x)
		if shift := 64 - uint(bitlen); x != float64(ux) || ux != (ux<<shift)>>shift {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return ux, d.Enc.Err
	}
	return 0, d.Close(fmt.Errorf("vdl: incompatible decode from %v into uint%d", tt, bitlen))
}

func (e *pipeEncoder) EncodeInt(v int64) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.ArgInt = v
	e.NumberType = numberInt
	return e.Err
}

func (d *pipeDecoder) DecodeInt(bitlen int) (int64, error) {
	const errFmt = "vdl: conversion from %v into int%d loses precision: %v"
	top, tt := d.top(), d.Type()
	if top == nil {
		return 0, d.Close(errEmptyPipeStack)
	}
	switch d.Enc.NumberType {
	case numberUint:
		x := d.Enc.ArgUint
		if d.Enc.DecBytesAsEntries {
			x = uint64(d.Enc.ArgBytes[top.Index])
		}
		ix := int64(x)
		// The shift uses 65 since the topmost bit is the sign bit.  I.e. 32 bit
		// numbers should be shifted by 33 rather than 32.
		if shift := 65 - uint(bitlen); ix < 0 || x != (x<<shift)>>shift {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return ix, d.Enc.Err
	case numberInt:
		x := d.Enc.ArgInt
		if shift := 64 - uint(bitlen); x != (x<<shift)>>shift {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return x, d.Enc.Err
	case numberFloat:
		x := d.Enc.ArgFloat
		ix := int64(x)
		if shift := 64 - uint(bitlen); x != float64(ix) || ix != (ix<<shift)>>shift {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return ix, d.Enc.Err
	}
	return 0, d.Close(fmt.Errorf("vdl: incompatible decode from %v into int%d", tt, bitlen))
}

func (e *pipeEncoder) EncodeFloat(v float64) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.ArgFloat = v
	e.NumberType = numberFloat
	return e.Err
}

func (d *pipeDecoder) DecodeFloat(bitlen int) (float64, error) {
	const errFmt = "vdl: conversion from %v into float%d loses precision: %v"
	top, tt := d.top(), d.Type()
	if top == nil {
		return 0, d.Close(errEmptyPipeStack)
	}
	switch d.Enc.NumberType {
	case numberUint:
		x := d.Enc.ArgUint
		if d.Enc.DecBytesAsEntries {
			x = uint64(d.Enc.ArgBytes[top.Index])
		}
		var max uint64
		if bitlen > 32 {
			max = float64MaxInt
		} else {
			max = float32MaxInt
		}
		if x > max {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return float64(x), d.Enc.Err
	case numberInt:
		x := d.Enc.ArgInt
		var min, max int64
		if bitlen > 32 {
			min, max = float64MinInt, float64MaxInt
		} else {
			min, max = float32MinInt, float32MaxInt
		}
		if x < min || x > max {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return float64(x), d.Enc.Err
	case numberFloat:
		x := d.Enc.ArgFloat
		if bitlen <= 32 && (x < -math.MaxFloat32 || x > math.MaxFloat32) {
			return 0, d.Close(fmt.Errorf(errFmt, tt, bitlen, x))
		}
		return x, d.Enc.Err
	}
	return 0, d.Close(fmt.Errorf("vdl: incompatible decode from %v into float%d", tt, bitlen))
}

func (e *pipeEncoder) EncodeBytes(v []byte) error {
	if e.State == pipeStateDecoder {
		return e.Close(errEncCallDuringDecPhase)
	}
	e.EncIsBytes = true
	e.ArgBytes = v
	e.NumberType = numberUint
	return e.Err
}

func (d *pipeDecoder) DecodeBytes(fixedLen int, value *[]byte) error {
	top := d.top()
	if top == nil {
		return d.Close(errEmptyPipeStack)
	}
	if !d.Enc.EncIsBytes {
		if err := DecodeConvertedBytes(d, fixedLen, value); err != nil {
			return d.Close(err)
		}
		return nil
	}
	len := len(d.Enc.ArgBytes)
	switch {
	case fixedLen >= 0 && fixedLen != len:
		return d.Close(fmt.Errorf("vdl: got %d bytes, want fixed len %d, %v", len, fixedLen, d.Type()))
	case len == 0:
		*value = nil
		return nil
	case fixedLen >= 0:
		// Only re-use the existing buffer if we're filling in an array.  This
		// sacrifices some performance, but also avoids bugs when repeatedly
		// decoding into the same value.
		*value = (*value)[:len]
	default:
		*value = make([]byte, len)
	}
	copy(*value, d.Enc.ArgBytes)
	return d.Enc.Err
}
