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

// PublicChatTypeHasUsername represents TL type `publicChatTypeHasUsername#14e8a07e`.
type PublicChatTypeHasUsername struct {
}

// PublicChatTypeHasUsernameTypeID is TL type id of PublicChatTypeHasUsername.
const PublicChatTypeHasUsernameTypeID = 0x14e8a07e

// construct implements constructor of PublicChatTypeClass.
func (p PublicChatTypeHasUsername) construct() PublicChatTypeClass { return &p }

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

	_ PublicChatTypeClass = &PublicChatTypeHasUsername{}
)

func (p *PublicChatTypeHasUsername) Zero() bool {
	if p == nil {
		return true
	}

	return true
}

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

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

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

// TypeInfo returns info about TL type.
func (p *PublicChatTypeHasUsername) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "publicChatTypeHasUsername",
		ID:   PublicChatTypeHasUsernameTypeID,
	}
	if p == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (p *PublicChatTypeHasUsername) Encode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode publicChatTypeHasUsername#14e8a07e as nil")
	}
	b.PutID(PublicChatTypeHasUsernameTypeID)
	return p.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (p *PublicChatTypeHasUsername) EncodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode publicChatTypeHasUsername#14e8a07e as nil")
	}
	return nil
}

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

// DecodeBare implements bin.BareDecoder.
func (p *PublicChatTypeHasUsername) DecodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode publicChatTypeHasUsername#14e8a07e to nil")
	}
	return nil
}

// EncodeTDLibJSON implements tdjson.TDLibEncoder.
func (p *PublicChatTypeHasUsername) EncodeTDLibJSON(b tdjson.Encoder) error {
	if p == nil {
		return fmt.Errorf("can't encode publicChatTypeHasUsername#14e8a07e as nil")
	}
	b.ObjStart()
	b.PutID("publicChatTypeHasUsername")
	b.Comma()
	b.StripComma()
	b.ObjEnd()
	return nil
}

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

	return b.Obj(func(b tdjson.Decoder, key []byte) error {
		switch string(key) {
		case tdjson.TypeField:
			if err := b.ConsumeID("publicChatTypeHasUsername"); err != nil {
				return fmt.Errorf("unable to decode publicChatTypeHasUsername#14e8a07e: %w", err)
			}
		default:
			return b.Skip()
		}
		return nil
	})
}

// PublicChatTypeIsLocationBased represents TL type `publicChatTypeIsLocationBased#468e6090`.
type PublicChatTypeIsLocationBased struct {
}

// PublicChatTypeIsLocationBasedTypeID is TL type id of PublicChatTypeIsLocationBased.
const PublicChatTypeIsLocationBasedTypeID = 0x468e6090

// construct implements constructor of PublicChatTypeClass.
func (p PublicChatTypeIsLocationBased) construct() PublicChatTypeClass { return &p }

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

	_ PublicChatTypeClass = &PublicChatTypeIsLocationBased{}
)

func (p *PublicChatTypeIsLocationBased) Zero() bool {
	if p == nil {
		return true
	}

	return true
}

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

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

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

// TypeInfo returns info about TL type.
func (p *PublicChatTypeIsLocationBased) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "publicChatTypeIsLocationBased",
		ID:   PublicChatTypeIsLocationBasedTypeID,
	}
	if p == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{}
	return typ
}

// Encode implements bin.Encoder.
func (p *PublicChatTypeIsLocationBased) Encode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode publicChatTypeIsLocationBased#468e6090 as nil")
	}
	b.PutID(PublicChatTypeIsLocationBasedTypeID)
	return p.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (p *PublicChatTypeIsLocationBased) EncodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode publicChatTypeIsLocationBased#468e6090 as nil")
	}
	return nil
}

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

// DecodeBare implements bin.BareDecoder.
func (p *PublicChatTypeIsLocationBased) DecodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode publicChatTypeIsLocationBased#468e6090 to nil")
	}
	return nil
}

// EncodeTDLibJSON implements tdjson.TDLibEncoder.
func (p *PublicChatTypeIsLocationBased) EncodeTDLibJSON(b tdjson.Encoder) error {
	if p == nil {
		return fmt.Errorf("can't encode publicChatTypeIsLocationBased#468e6090 as nil")
	}
	b.ObjStart()
	b.PutID("publicChatTypeIsLocationBased")
	b.Comma()
	b.StripComma()
	b.ObjEnd()
	return nil
}

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

	return b.Obj(func(b tdjson.Decoder, key []byte) error {
		switch string(key) {
		case tdjson.TypeField:
			if err := b.ConsumeID("publicChatTypeIsLocationBased"); err != nil {
				return fmt.Errorf("unable to decode publicChatTypeIsLocationBased#468e6090: %w", err)
			}
		default:
			return b.Skip()
		}
		return nil
	})
}

// PublicChatTypeClassName is schema name of PublicChatTypeClass.
const PublicChatTypeClassName = "PublicChatType"

// PublicChatTypeClass represents PublicChatType generic type.
//
// Example:
//
//	g, err := tdapi.DecodePublicChatType(buf)
//	if err != nil {
//	    panic(err)
//	}
//	switch v := g.(type) {
//	case *tdapi.PublicChatTypeHasUsername: // publicChatTypeHasUsername#14e8a07e
//	case *tdapi.PublicChatTypeIsLocationBased: // publicChatTypeIsLocationBased#468e6090
//	default: panic(v)
//	}
type PublicChatTypeClass interface {
	bin.Encoder
	bin.Decoder
	bin.BareEncoder
	bin.BareDecoder
	construct() PublicChatTypeClass

	// 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

	EncodeTDLibJSON(b tdjson.Encoder) error
	DecodeTDLibJSON(b tdjson.Decoder) error
}

// DecodePublicChatType implements binary de-serialization for PublicChatTypeClass.
func DecodePublicChatType(buf *bin.Buffer) (PublicChatTypeClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case PublicChatTypeHasUsernameTypeID:
		// Decoding publicChatTypeHasUsername#14e8a07e.
		v := PublicChatTypeHasUsername{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PublicChatTypeClass: %w", err)
		}
		return &v, nil
	case PublicChatTypeIsLocationBasedTypeID:
		// Decoding publicChatTypeIsLocationBased#468e6090.
		v := PublicChatTypeIsLocationBased{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PublicChatTypeClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode PublicChatTypeClass: %w", bin.NewUnexpectedID(id))
	}
}

// DecodeTDLibJSONPublicChatType implements binary de-serialization for PublicChatTypeClass.
func DecodeTDLibJSONPublicChatType(buf tdjson.Decoder) (PublicChatTypeClass, error) {
	id, err := buf.FindTypeID()
	if err != nil {
		return nil, err
	}
	switch id {
	case "publicChatTypeHasUsername":
		// Decoding publicChatTypeHasUsername#14e8a07e.
		v := PublicChatTypeHasUsername{}
		if err := v.DecodeTDLibJSON(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PublicChatTypeClass: %w", err)
		}
		return &v, nil
	case "publicChatTypeIsLocationBased":
		// Decoding publicChatTypeIsLocationBased#468e6090.
		v := PublicChatTypeIsLocationBased{}
		if err := v.DecodeTDLibJSON(buf); err != nil {
			return nil, fmt.Errorf("unable to decode PublicChatTypeClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode PublicChatTypeClass: %w", tdjson.NewUnexpectedID(id))
	}
}

// PublicChatType boxes the PublicChatTypeClass providing a helper.
type PublicChatTypeBox struct {
	PublicChatType PublicChatTypeClass
}

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

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

// DecodeTDLibJSON implements bin.Decoder for PublicChatTypeBox.
func (b *PublicChatTypeBox) DecodeTDLibJSON(buf tdjson.Decoder) error {
	if b == nil {
		return fmt.Errorf("unable to decode PublicChatTypeBox to nil")
	}
	v, err := DecodeTDLibJSONPublicChatType(buf)
	if err != nil {
		return fmt.Errorf("unable to decode boxed value: %w", err)
	}
	b.PublicChatType = v
	return nil
}

// EncodeTDLibJSON implements bin.Encode for PublicChatTypeBox.
func (b *PublicChatTypeBox) EncodeTDLibJSON(buf tdjson.Encoder) error {
	if b == nil || b.PublicChatType == nil {
		return fmt.Errorf("unable to encode PublicChatTypeClass as nil")
	}
	return b.PublicChatType.EncodeTDLibJSON(buf)
}
