package avro

import (
	
	
)

func createSkipDecoder( Schema) ValDecoder {
	switch .Type() {
	case Boolean:
		return &boolSkipDecoder{}

	case Int:
		return &intSkipDecoder{}

	case Long:
		return &longSkipDecoder{}

	case Float:
		return &floatSkipDecoder{}

	case Double:
		return &doubleSkipDecoder{}

	case String:
		return &stringSkipDecoder{}

	case Bytes:
		return &bytesSkipDecoder{}

	case Record:
		return skipDecoderOfRecord()

	case Ref:
		return (.(*RefSchema).Schema())

	case Enum:
		return &enumSkipDecoder{symbols: .(*EnumSchema).Symbols()}

	case Array:
		return skipDecoderOfArray()

	case Map:
		return skipDecoderOfMap()

	case Union:
		return skipDecoderOfUnion()

	case Fixed:
		return &fixedSkipDecoder{size: .(*FixedSchema).Size()}

	default:
		return &errorDecoder{err: fmt.Errorf("avro: schema type %s is unsupported", .Type())}
	}
}

type boolSkipDecoder struct{}

func (*boolSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipBool()
}

type intSkipDecoder struct{}

func (*intSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipInt()
}

type longSkipDecoder struct{}

func (*longSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipLong()
}

type floatSkipDecoder struct{}

func (*floatSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipFloat()
}

type doubleSkipDecoder struct{}

func (*doubleSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipDouble()
}

type stringSkipDecoder struct{}

func (*stringSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipString()
}

type bytesSkipDecoder struct{}

func ( *bytesSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipBytes()
}

func skipDecoderOfRecord( Schema) ValDecoder {
	 := .(*RecordSchema)

	 := make([]ValDecoder, len(.Fields()))
	for ,  := range .Fields() {
		[] = createSkipDecoder(.Type())
	}

	return &recordSkipDecoder{
		decoders: ,
	}
}

type recordSkipDecoder struct {
	decoders []ValDecoder
}

func ( *recordSkipDecoder) ( unsafe.Pointer,  *Reader) {
	for ,  := range .decoders {
		.Decode(nil, )
	}
}

type enumSkipDecoder struct {
	symbols []string
}

func ( *enumSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipInt()
}

func skipDecoderOfArray( Schema) ValDecoder {
	 := .(*ArraySchema)
	 := createSkipDecoder(.Items())

	return &sliceSkipDecoder{
		decoder: ,
	}
}

type sliceSkipDecoder struct {
	decoder ValDecoder
}

func ( *sliceSkipDecoder) ( unsafe.Pointer,  *Reader) {
	for {
		,  := .ReadBlockHeader()
		if  == 0 {
			break
		}

		if  > 0 {
			.SkipNBytes(int())
			continue
		}

		for range  {
			.decoder.Decode(nil, )
		}
	}
}

func skipDecoderOfMap( Schema) ValDecoder {
	 := .(*MapSchema)
	 := createSkipDecoder(.Values())

	return &mapSkipDecoder{
		decoder: ,
	}
}

type mapSkipDecoder struct {
	decoder ValDecoder
}

func ( *mapSkipDecoder) ( unsafe.Pointer,  *Reader) {
	for {
		,  := .ReadBlockHeader()
		if  == 0 {
			break
		}

		if  > 0 {
			.SkipNBytes(int())
			continue
		}

		for range  {
			.SkipString()
			.decoder.Decode(nil, )
		}
	}
}

func skipDecoderOfUnion( Schema) ValDecoder {
	 := .(*UnionSchema)

	return &unionSkipDecoder{
		schema: ,
	}
}

type unionSkipDecoder struct {
	schema *UnionSchema
}

func ( *unionSkipDecoder) ( unsafe.Pointer,  *Reader) {
	,  := getUnionSchema(.schema, )
	if  == nil {
		return
	}

	// In a null case, just return
	if .Type() == Null {
		return
	}

	createSkipDecoder().Decode(nil, )
}

type fixedSkipDecoder struct {
	size int
}

func ( *fixedSkipDecoder) ( unsafe.Pointer,  *Reader) {
	.SkipNBytes(.size)
}