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

// Transcode transcodes from the decoder to the encoder.
func Transcode(e Encoder, d Decoder) error {
	if err := d.StartValue(); err != nil {
		return err
	}
	if d.IsNil() {
		if err := e.NilValue(d.Type()); err != nil {
			return err
		}
		return d.FinishValue()
	}
	if d.IsOptional() {
		e.SetNextStartValueIsOptional()
	}
	if err := e.StartValue(d.Type()); err != nil {
		return err
	}
	if err := transcodeNonNilValue(e, d); err != nil {
		return err
	}
	if err := d.FinishValue(); err != nil {
		return err
	}
	return e.FinishValue()
}

func transcodeNonNilValue(e Encoder, d Decoder) error {
	if d.Type().IsBytes() {
		var b []byte
		fixedLen := -1
		if d.Type().Kind() == Array {
			fixedLen = d.Type().Len()
		}
		if err := d.DecodeBytes(fixedLen, &b); err != nil {
			return err
		}
		return e.EncodeBytes(b)
	}
	switch d.Type().Kind() {
	case Bool:
		val, err := d.DecodeBool()
		if err != nil {
			return err
		}
		return e.EncodeBool(val)
	case Byte, Uint16, Uint32, Uint64:
		val, err := d.DecodeUint(d.Type().Kind().BitLen())
		if err != nil {
			return err
		}
		return e.EncodeUint(val)
	case Int8, Int16, Int32, Int64:
		val, err := d.DecodeInt(d.Type().Kind().BitLen())
		if err != nil {
			return err
		}
		return e.EncodeInt(val)
	case Float32, Float64:
		val, err := d.DecodeFloat(d.Type().Kind().BitLen())
		if err != nil {
			return err
		}
		return e.EncodeFloat(val)
	case String, Enum:
		val, err := d.DecodeString()
		if err != nil {
			return err
		}
		return e.EncodeString(val)
	case TypeObject:
		val, err := d.DecodeTypeObject()
		if err != nil {
			return err
		}
		return e.EncodeTypeObject(val)
	case List, Array, Set:
		return transcodeListOrArrayOrSet(e, d)
	case Map:
		return transcodeMap(e, d)
	case Struct, Union:
		return transcodeStructOrUnion(e, d)
	}
	panic("unhandled kind")
}

func transcodeListOrArrayOrSet(e Encoder, d Decoder) error {
	if err := e.SetLenHint(d.LenHint()); err != nil {
		return err
	}
	for {
		switch done, err := d.NextEntry(); {
		case err != nil:
			return err
		case done:
			return e.NextEntry(true)
		default:
			if err := e.NextEntry(false); err != nil {
				return err
			}
			if err := Transcode(e, d); err != nil {
				return err
			}
		}
	}
}

func transcodeMap(e Encoder, d Decoder) error {
	if err := e.SetLenHint(d.LenHint()); err != nil {
		return err
	}
	for {
		switch done, err := d.NextEntry(); {
		case err != nil:
			return err
		case done:
			return e.NextEntry(true)
		default:
			if err := e.NextEntry(false); err != nil {
				return err
			}
			if err := Transcode(e, d); err != nil {
				return err
			}
			if err := Transcode(e, d); err != nil {
				return err
			}
		}
	}
}

func transcodeStructOrUnion(e Encoder, d Decoder) error {
	for {
		switch name, err := d.NextField(); {
		case err != nil:
			return err
		case name == "":
			return e.NextField("")
		default:
			if err := e.NextField(name); err != nil {
				return err
			}
			if err := Transcode(e, d); err != nil {
				return err
			}
		}
	}
}
