// Code generated by gotdgen, DO NOT EDIT.

package tg

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{}
)

// AuthCodeTypeSMS represents TL type `auth.codeTypeSms#72a3158c`.
// The next time, the authentication code will be delivered via an immediately canceled
// incoming call.
//
// See https://core.telegram.org/constructor/auth.codeTypeSms for reference.
type AuthCodeTypeSMS struct {
}

// AuthCodeTypeSMSTypeID is TL type id of AuthCodeTypeSMS.
const AuthCodeTypeSMSTypeID = 0x72a3158c

// construct implements constructor of AuthCodeTypeClass.
func (c AuthCodeTypeSMS) construct() AuthCodeTypeClass { return &c }

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

	_ AuthCodeTypeClass = &AuthCodeTypeSMS{}
)

func (c *AuthCodeTypeSMS) Zero() bool {
	if c == nil {
		return true
	}

	return true
}

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

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

// TypeName returns name of type in TL schema.
func (*AuthCodeTypeSMS) TypeName() string {
	return "auth.codeTypeSms"
}

// TypeInfo returns info about TL type.
func (c *AuthCodeTypeSMS) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "auth.codeTypeSms",
		ID:   AuthCodeTypeSMSTypeID,
	}
	if c == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (c *AuthCodeTypeSMS) Encode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeSms#72a3158c as nil")
	}
	b.PutID(AuthCodeTypeSMSTypeID)
	return c.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (c *AuthCodeTypeSMS) EncodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeSms#72a3158c as nil")
	}
	return nil
}

// Decode implements bin.Decoder.
func (c *AuthCodeTypeSMS) Decode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeSms#72a3158c to nil")
	}
	if err := b.ConsumeID(AuthCodeTypeSMSTypeID); err != nil {
		return fmt.Errorf("unable to decode auth.codeTypeSms#72a3158c: %w", err)
	}
	return c.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (c *AuthCodeTypeSMS) DecodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeSms#72a3158c to nil")
	}
	return nil
}

// AuthCodeTypeCall represents TL type `auth.codeTypeCall#741cd3e3`.
// The next time, the authentication code is to be delivered via an outgoing phone call.
//
// See https://core.telegram.org/constructor/auth.codeTypeCall for reference.
type AuthCodeTypeCall struct {
}

// AuthCodeTypeCallTypeID is TL type id of AuthCodeTypeCall.
const AuthCodeTypeCallTypeID = 0x741cd3e3

// construct implements constructor of AuthCodeTypeClass.
func (c AuthCodeTypeCall) construct() AuthCodeTypeClass { return &c }

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

	_ AuthCodeTypeClass = &AuthCodeTypeCall{}
)

func (c *AuthCodeTypeCall) Zero() bool {
	if c == nil {
		return true
	}

	return true
}

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

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

// TypeName returns name of type in TL schema.
func (*AuthCodeTypeCall) TypeName() string {
	return "auth.codeTypeCall"
}

// TypeInfo returns info about TL type.
func (c *AuthCodeTypeCall) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "auth.codeTypeCall",
		ID:   AuthCodeTypeCallTypeID,
	}
	if c == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (c *AuthCodeTypeCall) Encode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeCall#741cd3e3 as nil")
	}
	b.PutID(AuthCodeTypeCallTypeID)
	return c.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (c *AuthCodeTypeCall) EncodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeCall#741cd3e3 as nil")
	}
	return nil
}

// Decode implements bin.Decoder.
func (c *AuthCodeTypeCall) Decode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeCall#741cd3e3 to nil")
	}
	if err := b.ConsumeID(AuthCodeTypeCallTypeID); err != nil {
		return fmt.Errorf("unable to decode auth.codeTypeCall#741cd3e3: %w", err)
	}
	return c.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (c *AuthCodeTypeCall) DecodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeCall#741cd3e3 to nil")
	}
	return nil
}

// AuthCodeTypeFlashCall represents TL type `auth.codeTypeFlashCall#226ccefb`.
// The next time, the authentication code will be delivered via an immediately canceled
// incoming call.
//
// See https://core.telegram.org/constructor/auth.codeTypeFlashCall for reference.
type AuthCodeTypeFlashCall struct {
}

// AuthCodeTypeFlashCallTypeID is TL type id of AuthCodeTypeFlashCall.
const AuthCodeTypeFlashCallTypeID = 0x226ccefb

// construct implements constructor of AuthCodeTypeClass.
func (c AuthCodeTypeFlashCall) construct() AuthCodeTypeClass { return &c }

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

	_ AuthCodeTypeClass = &AuthCodeTypeFlashCall{}
)

func (c *AuthCodeTypeFlashCall) Zero() bool {
	if c == nil {
		return true
	}

	return true
}

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

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

// TypeName returns name of type in TL schema.
func (*AuthCodeTypeFlashCall) TypeName() string {
	return "auth.codeTypeFlashCall"
}

// TypeInfo returns info about TL type.
func (c *AuthCodeTypeFlashCall) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "auth.codeTypeFlashCall",
		ID:   AuthCodeTypeFlashCallTypeID,
	}
	if c == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (c *AuthCodeTypeFlashCall) Encode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeFlashCall#226ccefb as nil")
	}
	b.PutID(AuthCodeTypeFlashCallTypeID)
	return c.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (c *AuthCodeTypeFlashCall) EncodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeFlashCall#226ccefb as nil")
	}
	return nil
}

// Decode implements bin.Decoder.
func (c *AuthCodeTypeFlashCall) Decode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeFlashCall#226ccefb to nil")
	}
	if err := b.ConsumeID(AuthCodeTypeFlashCallTypeID); err != nil {
		return fmt.Errorf("unable to decode auth.codeTypeFlashCall#226ccefb: %w", err)
	}
	return c.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (c *AuthCodeTypeFlashCall) DecodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeFlashCall#226ccefb to nil")
	}
	return nil
}

// AuthCodeTypeMissedCall represents TL type `auth.codeTypeMissedCall#d61ad6ee`.
// The next time, the authentication code will be delivered via an immediately canceled
// incoming call, handled manually by the user.
//
// See https://core.telegram.org/constructor/auth.codeTypeMissedCall for reference.
type AuthCodeTypeMissedCall struct {
}

// AuthCodeTypeMissedCallTypeID is TL type id of AuthCodeTypeMissedCall.
const AuthCodeTypeMissedCallTypeID = 0xd61ad6ee

// construct implements constructor of AuthCodeTypeClass.
func (c AuthCodeTypeMissedCall) construct() AuthCodeTypeClass { return &c }

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

	_ AuthCodeTypeClass = &AuthCodeTypeMissedCall{}
)

func (c *AuthCodeTypeMissedCall) Zero() bool {
	if c == nil {
		return true
	}

	return true
}

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

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

// TypeName returns name of type in TL schema.
func (*AuthCodeTypeMissedCall) TypeName() string {
	return "auth.codeTypeMissedCall"
}

// TypeInfo returns info about TL type.
func (c *AuthCodeTypeMissedCall) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "auth.codeTypeMissedCall",
		ID:   AuthCodeTypeMissedCallTypeID,
	}
	if c == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (c *AuthCodeTypeMissedCall) Encode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeMissedCall#d61ad6ee as nil")
	}
	b.PutID(AuthCodeTypeMissedCallTypeID)
	return c.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (c *AuthCodeTypeMissedCall) EncodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeMissedCall#d61ad6ee as nil")
	}
	return nil
}

// Decode implements bin.Decoder.
func (c *AuthCodeTypeMissedCall) Decode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeMissedCall#d61ad6ee to nil")
	}
	if err := b.ConsumeID(AuthCodeTypeMissedCallTypeID); err != nil {
		return fmt.Errorf("unable to decode auth.codeTypeMissedCall#d61ad6ee: %w", err)
	}
	return c.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (c *AuthCodeTypeMissedCall) DecodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeMissedCall#d61ad6ee to nil")
	}
	return nil
}

// AuthCodeTypeFragmentSMS represents TL type `auth.codeTypeFragmentSms#6ed998c`.
// The next time, the authentication code will be delivered via fragment.com¹
//
// Links:
//  1. https://fragment.com
//
// See https://core.telegram.org/constructor/auth.codeTypeFragmentSms for reference.
type AuthCodeTypeFragmentSMS struct {
}

// AuthCodeTypeFragmentSMSTypeID is TL type id of AuthCodeTypeFragmentSMS.
const AuthCodeTypeFragmentSMSTypeID = 0x6ed998c

// construct implements constructor of AuthCodeTypeClass.
func (c AuthCodeTypeFragmentSMS) construct() AuthCodeTypeClass { return &c }

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

	_ AuthCodeTypeClass = &AuthCodeTypeFragmentSMS{}
)

func (c *AuthCodeTypeFragmentSMS) Zero() bool {
	if c == nil {
		return true
	}

	return true
}

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

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

// TypeName returns name of type in TL schema.
func (*AuthCodeTypeFragmentSMS) TypeName() string {
	return "auth.codeTypeFragmentSms"
}

// TypeInfo returns info about TL type.
func (c *AuthCodeTypeFragmentSMS) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "auth.codeTypeFragmentSms",
		ID:   AuthCodeTypeFragmentSMSTypeID,
	}
	if c == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (c *AuthCodeTypeFragmentSMS) Encode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeFragmentSms#6ed998c as nil")
	}
	b.PutID(AuthCodeTypeFragmentSMSTypeID)
	return c.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (c *AuthCodeTypeFragmentSMS) EncodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't encode auth.codeTypeFragmentSms#6ed998c as nil")
	}
	return nil
}

// Decode implements bin.Decoder.
func (c *AuthCodeTypeFragmentSMS) Decode(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeFragmentSms#6ed998c to nil")
	}
	if err := b.ConsumeID(AuthCodeTypeFragmentSMSTypeID); err != nil {
		return fmt.Errorf("unable to decode auth.codeTypeFragmentSms#6ed998c: %w", err)
	}
	return c.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (c *AuthCodeTypeFragmentSMS) DecodeBare(b *bin.Buffer) error {
	if c == nil {
		return fmt.Errorf("can't decode auth.codeTypeFragmentSms#6ed998c to nil")
	}
	return nil
}

// AuthCodeTypeClassName is schema name of AuthCodeTypeClass.
const AuthCodeTypeClassName = "auth.CodeType"

// AuthCodeTypeClass represents auth.CodeType generic type.
//
// See https://core.telegram.org/type/auth.CodeType for reference.
//
// Example:
//
//	g, err := tg.DecodeAuthCodeType(buf)
//	if err != nil {
//	    panic(err)
//	}
//	switch v := g.(type) {
//	case *tg.AuthCodeTypeSMS: // auth.codeTypeSms#72a3158c
//	case *tg.AuthCodeTypeCall: // auth.codeTypeCall#741cd3e3
//	case *tg.AuthCodeTypeFlashCall: // auth.codeTypeFlashCall#226ccefb
//	case *tg.AuthCodeTypeMissedCall: // auth.codeTypeMissedCall#d61ad6ee
//	case *tg.AuthCodeTypeFragmentSMS: // auth.codeTypeFragmentSms#6ed998c
//	default: panic(v)
//	}
type AuthCodeTypeClass interface {
	bin.Encoder
	bin.Decoder
	bin.BareEncoder
	bin.BareDecoder
	construct() AuthCodeTypeClass

	// TypeID returns type id in TL schema.
	//
	// See https://core.telegram.org/mtproto/TL-tl#remarks.
	TypeID() uint32
	// TypeName returns name of type in TL schema.
	TypeName() string
	// String implements fmt.Stringer.
	String() string
	// Zero returns true if current object has a zero value.
	Zero() bool
}

// DecodeAuthCodeType implements binary de-serialization for AuthCodeTypeClass.
func DecodeAuthCodeType(buf *bin.Buffer) (AuthCodeTypeClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case AuthCodeTypeSMSTypeID:
		// Decoding auth.codeTypeSms#72a3158c.
		v := AuthCodeTypeSMS{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode AuthCodeTypeClass: %w", err)
		}
		return &v, nil
	case AuthCodeTypeCallTypeID:
		// Decoding auth.codeTypeCall#741cd3e3.
		v := AuthCodeTypeCall{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode AuthCodeTypeClass: %w", err)
		}
		return &v, nil
	case AuthCodeTypeFlashCallTypeID:
		// Decoding auth.codeTypeFlashCall#226ccefb.
		v := AuthCodeTypeFlashCall{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode AuthCodeTypeClass: %w", err)
		}
		return &v, nil
	case AuthCodeTypeMissedCallTypeID:
		// Decoding auth.codeTypeMissedCall#d61ad6ee.
		v := AuthCodeTypeMissedCall{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode AuthCodeTypeClass: %w", err)
		}
		return &v, nil
	case AuthCodeTypeFragmentSMSTypeID:
		// Decoding auth.codeTypeFragmentSms#6ed998c.
		v := AuthCodeTypeFragmentSMS{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode AuthCodeTypeClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode AuthCodeTypeClass: %w", bin.NewUnexpectedID(id))
	}
}

// AuthCodeType boxes the AuthCodeTypeClass providing a helper.
type AuthCodeTypeBox struct {
	CodeType AuthCodeTypeClass
}

// Decode implements bin.Decoder for AuthCodeTypeBox.
func (b *AuthCodeTypeBox) Decode(buf *bin.Buffer) error {
	if b == nil {
		return fmt.Errorf("unable to decode AuthCodeTypeBox to nil")
	}
	v, err := DecodeAuthCodeType(buf)
	if err != nil {
		return fmt.Errorf("unable to decode boxed value: %w", err)
	}
	b.CodeType = v
	return nil
}

// Encode implements bin.Encode for AuthCodeTypeBox.
func (b *AuthCodeTypeBox) Encode(buf *bin.Buffer) error {
	if b == nil || b.CodeType == nil {
		return fmt.Errorf("unable to encode AuthCodeTypeClass as nil")
	}
	return b.CodeType.Encode(buf)
}
