// Code generated by gotdgen, DO NOT EDIT.

package tdapi

import (
	"context"
	"errors"
	"fmt"
	"sort"
	"strings"

	"go.uber.org/multierr"

	"go.mau.fi/mautrix-telegram/pkg/gotd/bin"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tdjson"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tdp"
	"go.mau.fi/mautrix-telegram/pkg/gotd/tgerr"
)

// No-op definition for keeping imports.
var (
	_ = bin.Buffer{}
	_ = context.Background()
	_ = fmt.Stringer(nil)
	_ = strings.Builder{}
	_ = errors.Is
	_ = multierr.AppendInto
	_ = sort.Ints
	_ = tdp.Format
	_ = tgerr.Error{}
	_ = tdjson.Encoder{}
)

// PersonalDetails represents TL type `personalDetails#c0b869b7`.
type PersonalDetails struct {
	// First name of the user written in English; 1-255 characters
	FirstName string
	// Middle name of the user written in English; 0-255 characters
	MiddleName string
	// Last name of the user written in English; 1-255 characters
	LastName string
	// Native first name of the user; 1-255 characters
	NativeFirstName string
	// Native middle name of the user; 0-255 characters
	NativeMiddleName string
	// Native last name of the user; 1-255 characters
	NativeLastName string
	// Birthdate of the user
	Birthdate Date
	// Gender of the user, "male" or "female"
	Gender string
	// A two-letter ISO 3166-1 alpha-2 country code of the user's country
	CountryCode string
	// A two-letter ISO 3166-1 alpha-2 country code of the user's residence country
	ResidenceCountryCode string
}

// PersonalDetailsTypeID is TL type id of PersonalDetails.
const PersonalDetailsTypeID = 0xc0b869b7

// Ensuring interfaces in compile-time for PersonalDetails.
var (
	_ bin.Encoder     = &PersonalDetails{}
	_ bin.Decoder     = &PersonalDetails{}
	_ bin.BareEncoder = &PersonalDetails{}
	_ bin.BareDecoder = &PersonalDetails{}
)

func (p *PersonalDetails) Zero() bool {
	if p == nil {
		return true
	}
	if !(p.FirstName == "") {
		return false
	}
	if !(p.MiddleName == "") {
		return false
	}
	if !(p.LastName == "") {
		return false
	}
	if !(p.NativeFirstName == "") {
		return false
	}
	if !(p.NativeMiddleName == "") {
		return false
	}
	if !(p.NativeLastName == "") {
		return false
	}
	if !(p.Birthdate.Zero()) {
		return false
	}
	if !(p.Gender == "") {
		return false
	}
	if !(p.CountryCode == "") {
		return false
	}
	if !(p.ResidenceCountryCode == "") {
		return false
	}

	return true
}

// String implements fmt.Stringer.
func (p *PersonalDetails) String() string {
	if p == nil {
		return "PersonalDetails(nil)"
	}
	type Alias PersonalDetails
	return fmt.Sprintf("PersonalDetails%+v", Alias(*p))
}

// TypeID returns type id in TL schema.
//
// See https://core.telegram.org/mtproto/TL-tl#remarks.
func (*PersonalDetails) TypeID() uint32 {
	return PersonalDetailsTypeID
}

// TypeName returns name of type in TL schema.
func (*PersonalDetails) TypeName() string {
	return "personalDetails"
}

// TypeInfo returns info about TL type.
func (p *PersonalDetails) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "personalDetails",
		ID:   PersonalDetailsTypeID,
	}
	if p == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "FirstName",
			SchemaName: "first_name",
		},
		{
			Name:       "MiddleName",
			SchemaName: "middle_name",
		},
		{
			Name:       "LastName",
			SchemaName: "last_name",
		},
		{
			Name:       "NativeFirstName",
			SchemaName: "native_first_name",
		},
		{
			Name:       "NativeMiddleName",
			SchemaName: "native_middle_name",
		},
		{
			Name:       "NativeLastName",
			SchemaName: "native_last_name",
		},
		{
			Name:       "Birthdate",
			SchemaName: "birthdate",
		},
		{
			Name:       "Gender",
			SchemaName: "gender",
		},
		{
			Name:       "CountryCode",
			SchemaName: "country_code",
		},
		{
			Name:       "ResidenceCountryCode",
			SchemaName: "residence_country_code",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (p *PersonalDetails) Encode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode personalDetails#c0b869b7 as nil")
	}
	b.PutID(PersonalDetailsTypeID)
	return p.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (p *PersonalDetails) EncodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode personalDetails#c0b869b7 as nil")
	}
	b.PutString(p.FirstName)
	b.PutString(p.MiddleName)
	b.PutString(p.LastName)
	b.PutString(p.NativeFirstName)
	b.PutString(p.NativeMiddleName)
	b.PutString(p.NativeLastName)
	if err := p.Birthdate.Encode(b); err != nil {
		return fmt.Errorf("unable to encode personalDetails#c0b869b7: field birthdate: %w", err)
	}
	b.PutString(p.Gender)
	b.PutString(p.CountryCode)
	b.PutString(p.ResidenceCountryCode)
	return nil
}

// Decode implements bin.Decoder.
func (p *PersonalDetails) Decode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode personalDetails#c0b869b7 to nil")
	}
	if err := b.ConsumeID(PersonalDetailsTypeID); err != nil {
		return fmt.Errorf("unable to decode personalDetails#c0b869b7: %w", err)
	}
	return p.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (p *PersonalDetails) DecodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode personalDetails#c0b869b7 to nil")
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field first_name: %w", err)
		}
		p.FirstName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field middle_name: %w", err)
		}
		p.MiddleName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field last_name: %w", err)
		}
		p.LastName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field native_first_name: %w", err)
		}
		p.NativeFirstName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field native_middle_name: %w", err)
		}
		p.NativeMiddleName = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field native_last_name: %w", err)
		}
		p.NativeLastName = value
	}
	{
		if err := p.Birthdate.Decode(b); err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field birthdate: %w", err)
		}
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field gender: %w", err)
		}
		p.Gender = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field country_code: %w", err)
		}
		p.CountryCode = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode personalDetails#c0b869b7: field residence_country_code: %w", err)
		}
		p.ResidenceCountryCode = value
	}
	return nil
}

// EncodeTDLibJSON implements tdjson.TDLibEncoder.
func (p *PersonalDetails) EncodeTDLibJSON(b tdjson.Encoder) error {
	if p == nil {
		return fmt.Errorf("can't encode personalDetails#c0b869b7 as nil")
	}
	b.ObjStart()
	b.PutID("personalDetails")
	b.Comma()
	b.FieldStart("first_name")
	b.PutString(p.FirstName)
	b.Comma()
	b.FieldStart("middle_name")
	b.PutString(p.MiddleName)
	b.Comma()
	b.FieldStart("last_name")
	b.PutString(p.LastName)
	b.Comma()
	b.FieldStart("native_first_name")
	b.PutString(p.NativeFirstName)
	b.Comma()
	b.FieldStart("native_middle_name")
	b.PutString(p.NativeMiddleName)
	b.Comma()
	b.FieldStart("native_last_name")
	b.PutString(p.NativeLastName)
	b.Comma()
	b.FieldStart("birthdate")
	if err := p.Birthdate.EncodeTDLibJSON(b); err != nil {
		return fmt.Errorf("unable to encode personalDetails#c0b869b7: field birthdate: %w", err)
	}
	b.Comma()
	b.FieldStart("gender")
	b.PutString(p.Gender)
	b.Comma()
	b.FieldStart("country_code")
	b.PutString(p.CountryCode)
	b.Comma()
	b.FieldStart("residence_country_code")
	b.PutString(p.ResidenceCountryCode)
	b.Comma()
	b.StripComma()
	b.ObjEnd()
	return nil
}

// DecodeTDLibJSON implements tdjson.TDLibDecoder.
func (p *PersonalDetails) DecodeTDLibJSON(b tdjson.Decoder) error {
	if p == nil {
		return fmt.Errorf("can't decode personalDetails#c0b869b7 to nil")
	}

	return b.Obj(func(b tdjson.Decoder, key []byte) error {
		switch string(key) {
		case tdjson.TypeField:
			if err := b.ConsumeID("personalDetails"); err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: %w", err)
			}
		case "first_name":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field first_name: %w", err)
			}
			p.FirstName = value
		case "middle_name":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field middle_name: %w", err)
			}
			p.MiddleName = value
		case "last_name":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field last_name: %w", err)
			}
			p.LastName = value
		case "native_first_name":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field native_first_name: %w", err)
			}
			p.NativeFirstName = value
		case "native_middle_name":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field native_middle_name: %w", err)
			}
			p.NativeMiddleName = value
		case "native_last_name":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field native_last_name: %w", err)
			}
			p.NativeLastName = value
		case "birthdate":
			if err := p.Birthdate.DecodeTDLibJSON(b); err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field birthdate: %w", err)
			}
		case "gender":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field gender: %w", err)
			}
			p.Gender = value
		case "country_code":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field country_code: %w", err)
			}
			p.CountryCode = value
		case "residence_country_code":
			value, err := b.String()
			if err != nil {
				return fmt.Errorf("unable to decode personalDetails#c0b869b7: field residence_country_code: %w", err)
			}
			p.ResidenceCountryCode = value
		default:
			return b.Skip()
		}
		return nil
	})
}

// GetFirstName returns value of FirstName field.
func (p *PersonalDetails) GetFirstName() (value string) {
	if p == nil {
		return
	}
	return p.FirstName
}

// GetMiddleName returns value of MiddleName field.
func (p *PersonalDetails) GetMiddleName() (value string) {
	if p == nil {
		return
	}
	return p.MiddleName
}

// GetLastName returns value of LastName field.
func (p *PersonalDetails) GetLastName() (value string) {
	if p == nil {
		return
	}
	return p.LastName
}

// GetNativeFirstName returns value of NativeFirstName field.
func (p *PersonalDetails) GetNativeFirstName() (value string) {
	if p == nil {
		return
	}
	return p.NativeFirstName
}

// GetNativeMiddleName returns value of NativeMiddleName field.
func (p *PersonalDetails) GetNativeMiddleName() (value string) {
	if p == nil {
		return
	}
	return p.NativeMiddleName
}

// GetNativeLastName returns value of NativeLastName field.
func (p *PersonalDetails) GetNativeLastName() (value string) {
	if p == nil {
		return
	}
	return p.NativeLastName
}

// GetBirthdate returns value of Birthdate field.
func (p *PersonalDetails) GetBirthdate() (value Date) {
	if p == nil {
		return
	}
	return p.Birthdate
}

// GetGender returns value of Gender field.
func (p *PersonalDetails) GetGender() (value string) {
	if p == nil {
		return
	}
	return p.Gender
}

// GetCountryCode returns value of CountryCode field.
func (p *PersonalDetails) GetCountryCode() (value string) {
	if p == nil {
		return
	}
	return p.CountryCode
}

// GetResidenceCountryCode returns value of ResidenceCountryCode field.
func (p *PersonalDetails) GetResidenceCountryCode() (value string) {
	if p == nil {
		return
	}
	return p.ResidenceCountryCode
}
