// Code generated by ogen, DO NOT EDIT.

package api

import (
	"math/bits"
	"strconv"

	"github.com/go-faster/errors"

	"github.com/ogen-go/ogen/conv"
	"github.com/ogen-go/ogen/uri"
	"github.com/ogen-go/ogen/validate"
)

// EncodeURI encodes Pagination as URI form.
func (s *Pagination) EncodeURI(e uri.Encoder) error {
	if err := e.EncodeField("Page", func(e uri.Encoder) error {
		return e.EncodeValue(conv.Int32ToString(s.Page))
	}); err != nil {
		return errors.Wrap(err, "encode field \"Page\"")
	}
	if err := e.EncodeField("Limit", func(e uri.Encoder) error {
		return e.EncodeValue(conv.Int32ToString(s.Limit))
	}); err != nil {
		return errors.Wrap(err, "encode field \"Limit\"")
	}
	return nil
}

var uriFieldsNameOfPagination = [2]string{
	0: "Page",
	1: "Limit",
}

// DecodeURI decodes Pagination from URI form.
func (s *Pagination) DecodeURI(d uri.Decoder) error {
	if s == nil {
		return errors.New("invalid: unable to decode Pagination to nil")
	}
	var requiredBitSet [1]uint8

	if err := d.DecodeFields(func(k string, d uri.Decoder) error {
		switch k {
		case "Page":
			requiredBitSet[0] |= 1 << 0
			if err := func() error {
				val, err := d.DecodeValue()
				if err != nil {
					return err
				}

				c, err := conv.ToInt32(val)
				if err != nil {
					return err
				}

				s.Page = c
				return nil
			}(); err != nil {
				return errors.Wrap(err, "decode field \"Page\"")
			}
		case "Limit":
			requiredBitSet[0] |= 1 << 1
			if err := func() error {
				val, err := d.DecodeValue()
				if err != nil {
					return err
				}

				c, err := conv.ToInt32(val)
				if err != nil {
					return err
				}

				s.Limit = c
				return nil
			}(); err != nil {
				return errors.Wrap(err, "decode field \"Limit\"")
			}
		default:
			return nil
		}
		return nil
	}); err != nil {
		return errors.Wrap(err, "decode Pagination")
	}
	// Validate required fields.
	var failures []validate.FieldError
	for i, mask := range [1]uint8{
		0b00000011,
	} {
		if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
			// Mask only required fields and check equality to mask using XOR.
			//
			// If XOR result is not zero, result is not equal to expected, so some fields are missed.
			// Bits of fields which would be set are actually bits of missed fields.
			missed := bits.OnesCount8(result)
			for bitN := 0; bitN < missed; bitN++ {
				bitIdx := bits.TrailingZeros8(result)
				fieldIdx := i*8 + bitIdx
				var name string
				if fieldIdx < len(uriFieldsNameOfPagination) {
					name = uriFieldsNameOfPagination[fieldIdx]
				} else {
					name = strconv.Itoa(fieldIdx)
				}
				failures = append(failures, validate.FieldError{
					Name:  name,
					Error: validate.ErrFieldRequired,
				})
				// Reset bit.
				result &^= 1 << bitIdx
			}
		}
	}
	if len(failures) > 0 {
		return &validate.Error{Fields: failures}
	}

	return nil
}

// EncodeURI encodes SubmissionFilter as URI form.
func (s *SubmissionFilter) EncodeURI(e uri.Encoder) error {
	if err := e.EncodeField("ID", func(e uri.Encoder) error {
		if val, ok := s.ID.Get(); ok {
			return e.EncodeValue(conv.Int64ToString(val))
		}
		return nil
	}); err != nil {
		return errors.Wrap(err, "encode field \"ID\"")
	}
	if err := e.EncodeField("DisplayName", func(e uri.Encoder) error {
		if val, ok := s.DisplayName.Get(); ok {
			return e.EncodeValue(conv.StringToString(val))
		}
		return nil
	}); err != nil {
		return errors.Wrap(err, "encode field \"DisplayName\"")
	}
	if err := e.EncodeField("Creator", func(e uri.Encoder) error {
		if val, ok := s.Creator.Get(); ok {
			return e.EncodeValue(conv.StringToString(val))
		}
		return nil
	}); err != nil {
		return errors.Wrap(err, "encode field \"Creator\"")
	}
	if err := e.EncodeField("GameID", func(e uri.Encoder) error {
		if val, ok := s.GameID.Get(); ok {
			return e.EncodeValue(conv.Int32ToString(val))
		}
		return nil
	}); err != nil {
		return errors.Wrap(err, "encode field \"GameID\"")
	}
	if err := e.EncodeField("Date", func(e uri.Encoder) error {
		if val, ok := s.Date.Get(); ok {
			return e.EncodeValue(conv.Int64ToString(val))
		}
		return nil
	}); err != nil {
		return errors.Wrap(err, "encode field \"Date\"")
	}
	return nil
}

var uriFieldsNameOfSubmissionFilter = [5]string{
	0: "ID",
	1: "DisplayName",
	2: "Creator",
	3: "GameID",
	4: "Date",
}

// DecodeURI decodes SubmissionFilter from URI form.
func (s *SubmissionFilter) DecodeURI(d uri.Decoder) error {
	if s == nil {
		return errors.New("invalid: unable to decode SubmissionFilter to nil")
	}

	if err := d.DecodeFields(func(k string, d uri.Decoder) error {
		switch k {
		case "ID":
			if err := func() error {
				var sDotIDVal int64
				if err := func() error {
					val, err := d.DecodeValue()
					if err != nil {
						return err
					}

					c, err := conv.ToInt64(val)
					if err != nil {
						return err
					}

					sDotIDVal = c
					return nil
				}(); err != nil {
					return err
				}
				s.ID.SetTo(sDotIDVal)
				return nil
			}(); err != nil {
				return errors.Wrap(err, "decode field \"ID\"")
			}
		case "DisplayName":
			if err := func() error {
				var sDotDisplayNameVal string
				if err := func() error {
					val, err := d.DecodeValue()
					if err != nil {
						return err
					}

					c, err := conv.ToString(val)
					if err != nil {
						return err
					}

					sDotDisplayNameVal = c
					return nil
				}(); err != nil {
					return err
				}
				s.DisplayName.SetTo(sDotDisplayNameVal)
				return nil
			}(); err != nil {
				return errors.Wrap(err, "decode field \"DisplayName\"")
			}
		case "Creator":
			if err := func() error {
				var sDotCreatorVal string
				if err := func() error {
					val, err := d.DecodeValue()
					if err != nil {
						return err
					}

					c, err := conv.ToString(val)
					if err != nil {
						return err
					}

					sDotCreatorVal = c
					return nil
				}(); err != nil {
					return err
				}
				s.Creator.SetTo(sDotCreatorVal)
				return nil
			}(); err != nil {
				return errors.Wrap(err, "decode field \"Creator\"")
			}
		case "GameID":
			if err := func() error {
				var sDotGameIDVal int32
				if err := func() error {
					val, err := d.DecodeValue()
					if err != nil {
						return err
					}

					c, err := conv.ToInt32(val)
					if err != nil {
						return err
					}

					sDotGameIDVal = c
					return nil
				}(); err != nil {
					return err
				}
				s.GameID.SetTo(sDotGameIDVal)
				return nil
			}(); err != nil {
				return errors.Wrap(err, "decode field \"GameID\"")
			}
		case "Date":
			if err := func() error {
				var sDotDateVal int64
				if err := func() error {
					val, err := d.DecodeValue()
					if err != nil {
						return err
					}

					c, err := conv.ToInt64(val)
					if err != nil {
						return err
					}

					sDotDateVal = c
					return nil
				}(); err != nil {
					return err
				}
				s.Date.SetTo(sDotDateVal)
				return nil
			}(); err != nil {
				return errors.Wrap(err, "decode field \"Date\"")
			}
		default:
			return nil
		}
		return nil
	}); err != nil {
		return errors.Wrap(err, "decode SubmissionFilter")
	}

	return nil
}