// Code generated by github.com/actgardner/gogen-avro/v10. DO NOT EDIT.
/*
 * SOURCE:
 *     schema.avsc
 */
package avro

import (
	"encoding/json"
	"fmt"
	"io"

	"github.com/actgardner/gogen-avro/v10/compiler"
	"github.com/actgardner/gogen-avro/v10/vm"
	"github.com/actgardner/gogen-avro/v10/vm/types"
)

type UnionBytesStringRecord1Record2TypeEnum int

const (
	UnionBytesStringRecord1Record2TypeEnumBytes UnionBytesStringRecord1Record2TypeEnum = 0

	UnionBytesStringRecord1Record2TypeEnumString UnionBytesStringRecord1Record2TypeEnum = 1

	UnionBytesStringRecord1Record2TypeEnumRecord1 UnionBytesStringRecord1Record2TypeEnum = 2

	UnionBytesStringRecord1Record2TypeEnumRecord2 UnionBytesStringRecord1Record2TypeEnum = 3
)

type UnionBytesStringRecord1Record2 struct {
	Bytes     Bytes
	String    string
	Record1   Record1
	Record2   Record2
	UnionType UnionBytesStringRecord1Record2TypeEnum
}

func writeUnionBytesStringRecord1Record2(r UnionBytesStringRecord1Record2, w io.Writer) error {

	err := vm.WriteLong(int64(r.UnionType), w)
	if err != nil {
		return err
	}
	switch r.UnionType {
	case UnionBytesStringRecord1Record2TypeEnumBytes:
		return vm.WriteBytes(r.Bytes, w)
	case UnionBytesStringRecord1Record2TypeEnumString:
		return vm.WriteString(r.String, w)
	case UnionBytesStringRecord1Record2TypeEnumRecord1:
		return writeRecord1(r.Record1, w)
	case UnionBytesStringRecord1Record2TypeEnumRecord2:
		return writeRecord2(r.Record2, w)
	}
	return fmt.Errorf("invalid value for UnionBytesStringRecord1Record2")
}

func NewUnionBytesStringRecord1Record2() UnionBytesStringRecord1Record2 {
	return UnionBytesStringRecord1Record2{}
}

func (r UnionBytesStringRecord1Record2) Serialize(w io.Writer) error {
	return writeUnionBytesStringRecord1Record2(r, w)
}

func DeserializeUnionBytesStringRecord1Record2(r io.Reader) (UnionBytesStringRecord1Record2, error) {
	t := NewUnionBytesStringRecord1Record2()
	deser, err := compiler.CompileSchemaBytes([]byte(t.Schema()), []byte(t.Schema()))
	if err != nil {
		return t, err
	}

	err = vm.Eval(r, deser, &t)

	if err != nil {
		return t, err
	}
	return t, err
}

func DeserializeUnionBytesStringRecord1Record2FromSchema(r io.Reader, schema string) (UnionBytesStringRecord1Record2, error) {
	t := NewUnionBytesStringRecord1Record2()
	deser, err := compiler.CompileSchemaBytes([]byte(schema), []byte(t.Schema()))
	if err != nil {
		return t, err
	}

	err = vm.Eval(r, deser, &t)

	if err != nil {
		return t, err
	}
	return t, err
}

func (r UnionBytesStringRecord1Record2) Schema() string {
	return "[\"bytes\",\"string\",{\"fields\":[{\"name\":\"intfield\",\"type\":\"int\"}],\"name\":\"record1\",\"type\":\"record\"},{\"fields\":[{\"name\":\"intfield\",\"type\":\"int\"}],\"name\":\"record2\",\"type\":\"record\"}]"
}

func (_ UnionBytesStringRecord1Record2) SetBoolean(v bool)   { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) SetInt(v int32)      { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) SetFloat(v float32)  { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) SetDouble(v float64) { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) SetBytes(v []byte)   { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) SetString(v string)  { panic("Unsupported operation") }

func (r *UnionBytesStringRecord1Record2) SetLong(v int64) {

	r.UnionType = (UnionBytesStringRecord1Record2TypeEnum)(v)
}

func (r *UnionBytesStringRecord1Record2) Get(i int) types.Field {

	switch i {
	case 0:
		return &BytesWrapper{Target: (&r.Bytes)}
	case 1:
		return &types.String{Target: (&r.String)}
	case 2:
		r.Record1 = NewRecord1()
		return &types.Record{Target: (&r.Record1)}
	case 3:
		r.Record2 = NewRecord2()
		return &types.Record{Target: (&r.Record2)}
	}
	panic("Unknown field index")
}
func (_ UnionBytesStringRecord1Record2) NullField(i int)  { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) HintSize(i int)   { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) SetDefault(i int) { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) AppendMap(key string) types.Field {
	panic("Unsupported operation")
}
func (_ UnionBytesStringRecord1Record2) AppendArray() types.Field { panic("Unsupported operation") }
func (_ UnionBytesStringRecord1Record2) Finalize()                {}

func (r UnionBytesStringRecord1Record2) MarshalJSON() ([]byte, error) {

	switch r.UnionType {
	case UnionBytesStringRecord1Record2TypeEnumBytes:
		return json.Marshal(map[string]interface{}{"bytes": r.Bytes})
	case UnionBytesStringRecord1Record2TypeEnumString:
		return json.Marshal(map[string]interface{}{"string": r.String})
	case UnionBytesStringRecord1Record2TypeEnumRecord1:
		return json.Marshal(map[string]interface{}{"record1": r.Record1})
	case UnionBytesStringRecord1Record2TypeEnumRecord2:
		return json.Marshal(map[string]interface{}{"record2": r.Record2})
	}
	return nil, fmt.Errorf("invalid value for UnionBytesStringRecord1Record2")
}

func (r *UnionBytesStringRecord1Record2) UnmarshalJSON(data []byte) error {

	var fields map[string]json.RawMessage
	if err := json.Unmarshal(data, &fields); err != nil {
		return err
	}
	if len(fields) > 1 {
		return fmt.Errorf("more than one type supplied for union")
	}
	if value, ok := fields["bytes"]; ok {
		r.UnionType = 0
		return json.Unmarshal([]byte(value), &r.Bytes)
	}
	if value, ok := fields["string"]; ok {
		r.UnionType = 1
		return json.Unmarshal([]byte(value), &r.String)
	}
	if value, ok := fields["record1"]; ok {
		r.UnionType = 2
		return json.Unmarshal([]byte(value), &r.Record1)
	}
	if value, ok := fields["record2"]; ok {
		r.UnionType = 3
		return json.Unmarshal([]byte(value), &r.Record2)
	}
	return fmt.Errorf("invalid value for UnionBytesStringRecord1Record2")
}
