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

// AiComposeTone represents TL type `aiComposeTone#cff63ea9`.
//
// See https://core.telegram.org/constructor/aiComposeTone for reference.
type AiComposeTone struct {
	// Flags field of AiComposeTone.
	Flags bin.Fields
	// Creator field of AiComposeTone.
	Creator bool
	// ID field of AiComposeTone.
	ID int64
	// AccessHash field of AiComposeTone.
	AccessHash int64
	// Slug field of AiComposeTone.
	Slug string
	// Title field of AiComposeTone.
	Title string
	// EmojiID field of AiComposeTone.
	//
	// Use SetEmojiID and GetEmojiID helpers.
	EmojiID int64
	// Prompt field of AiComposeTone.
	//
	// Use SetPrompt and GetPrompt helpers.
	Prompt string
	// InstallsCount field of AiComposeTone.
	//
	// Use SetInstallsCount and GetInstallsCount helpers.
	InstallsCount int
	// AuthorID field of AiComposeTone.
	//
	// Use SetAuthorID and GetAuthorID helpers.
	AuthorID int64
	// ExampleEnglish field of AiComposeTone.
	//
	// Use SetExampleEnglish and GetExampleEnglish helpers.
	ExampleEnglish AiComposeToneExample
}

// AiComposeToneTypeID is TL type id of AiComposeTone.
const AiComposeToneTypeID = 0xcff63ea9

// construct implements constructor of AiComposeToneClass.
func (a AiComposeTone) construct() AiComposeToneClass { return &a }

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

	_ AiComposeToneClass = &AiComposeTone{}
)

func (a *AiComposeTone) Zero() bool {
	if a == nil {
		return true
	}
	if !(a.Flags.Zero()) {
		return false
	}
	if !(a.Creator == false) {
		return false
	}
	if !(a.ID == 0) {
		return false
	}
	if !(a.AccessHash == 0) {
		return false
	}
	if !(a.Slug == "") {
		return false
	}
	if !(a.Title == "") {
		return false
	}
	if !(a.EmojiID == 0) {
		return false
	}
	if !(a.Prompt == "") {
		return false
	}
	if !(a.InstallsCount == 0) {
		return false
	}
	if !(a.AuthorID == 0) {
		return false
	}
	if !(a.ExampleEnglish.Zero()) {
		return false
	}

	return true
}

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

// FillFrom fills AiComposeTone from given interface.
func (a *AiComposeTone) FillFrom(from interface {
	GetCreator() (value bool)
	GetID() (value int64)
	GetAccessHash() (value int64)
	GetSlug() (value string)
	GetTitle() (value string)
	GetEmojiID() (value int64, ok bool)
	GetPrompt() (value string, ok bool)
	GetInstallsCount() (value int, ok bool)
	GetAuthorID() (value int64, ok bool)
	GetExampleEnglish() (value AiComposeToneExample, ok bool)
}) {
	a.Creator = from.GetCreator()
	a.ID = from.GetID()
	a.AccessHash = from.GetAccessHash()
	a.Slug = from.GetSlug()
	a.Title = from.GetTitle()
	if val, ok := from.GetEmojiID(); ok {
		a.EmojiID = val
	}

	if val, ok := from.GetPrompt(); ok {
		a.Prompt = val
	}

	if val, ok := from.GetInstallsCount(); ok {
		a.InstallsCount = val
	}

	if val, ok := from.GetAuthorID(); ok {
		a.AuthorID = val
	}

	if val, ok := from.GetExampleEnglish(); ok {
		a.ExampleEnglish = val
	}

}

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

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

// TypeInfo returns info about TL type.
func (a *AiComposeTone) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "aiComposeTone",
		ID:   AiComposeToneTypeID,
	}
	if a == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Creator",
			SchemaName: "creator",
			Null:       !a.Flags.Has(0),
		},
		{
			Name:       "ID",
			SchemaName: "id",
		},
		{
			Name:       "AccessHash",
			SchemaName: "access_hash",
		},
		{
			Name:       "Slug",
			SchemaName: "slug",
		},
		{
			Name:       "Title",
			SchemaName: "title",
		},
		{
			Name:       "EmojiID",
			SchemaName: "emoji_id",
			Null:       !a.Flags.Has(1),
		},
		{
			Name:       "Prompt",
			SchemaName: "prompt",
			Null:       !a.Flags.Has(4),
		},
		{
			Name:       "InstallsCount",
			SchemaName: "installs_count",
			Null:       !a.Flags.Has(2),
		},
		{
			Name:       "AuthorID",
			SchemaName: "author_id",
			Null:       !a.Flags.Has(3),
		},
		{
			Name:       "ExampleEnglish",
			SchemaName: "example_english",
			Null:       !a.Flags.Has(5),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (a *AiComposeTone) SetFlags() {
	if !(a.Creator == false) {
		a.Flags.Set(0)
	}
	if !(a.EmojiID == 0) {
		a.Flags.Set(1)
	}
	if !(a.Prompt == "") {
		a.Flags.Set(4)
	}
	if !(a.InstallsCount == 0) {
		a.Flags.Set(2)
	}
	if !(a.AuthorID == 0) {
		a.Flags.Set(3)
	}
	if !(a.ExampleEnglish.Zero()) {
		a.Flags.Set(5)
	}
}

// Encode implements bin.Encoder.
func (a *AiComposeTone) Encode(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't encode aiComposeTone#cff63ea9 as nil")
	}
	b.PutID(AiComposeToneTypeID)
	return a.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (a *AiComposeTone) EncodeBare(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't encode aiComposeTone#cff63ea9 as nil")
	}
	a.SetFlags()
	if err := a.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode aiComposeTone#cff63ea9: field flags: %w", err)
	}
	b.PutLong(a.ID)
	b.PutLong(a.AccessHash)
	b.PutString(a.Slug)
	b.PutString(a.Title)
	if a.Flags.Has(1) {
		b.PutLong(a.EmojiID)
	}
	if a.Flags.Has(4) {
		b.PutString(a.Prompt)
	}
	if a.Flags.Has(2) {
		b.PutInt(a.InstallsCount)
	}
	if a.Flags.Has(3) {
		b.PutLong(a.AuthorID)
	}
	if a.Flags.Has(5) {
		if err := a.ExampleEnglish.Encode(b); err != nil {
			return fmt.Errorf("unable to encode aiComposeTone#cff63ea9: field example_english: %w", err)
		}
	}
	return nil
}

// Decode implements bin.Decoder.
func (a *AiComposeTone) Decode(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't decode aiComposeTone#cff63ea9 to nil")
	}
	if err := b.ConsumeID(AiComposeToneTypeID); err != nil {
		return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: %w", err)
	}
	return a.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (a *AiComposeTone) DecodeBare(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't decode aiComposeTone#cff63ea9 to nil")
	}
	{
		if err := a.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field flags: %w", err)
		}
	}
	a.Creator = a.Flags.Has(0)
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field id: %w", err)
		}
		a.ID = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field access_hash: %w", err)
		}
		a.AccessHash = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field slug: %w", err)
		}
		a.Slug = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field title: %w", err)
		}
		a.Title = value
	}
	if a.Flags.Has(1) {
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field emoji_id: %w", err)
		}
		a.EmojiID = value
	}
	if a.Flags.Has(4) {
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field prompt: %w", err)
		}
		a.Prompt = value
	}
	if a.Flags.Has(2) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field installs_count: %w", err)
		}
		a.InstallsCount = value
	}
	if a.Flags.Has(3) {
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field author_id: %w", err)
		}
		a.AuthorID = value
	}
	if a.Flags.Has(5) {
		if err := a.ExampleEnglish.Decode(b); err != nil {
			return fmt.Errorf("unable to decode aiComposeTone#cff63ea9: field example_english: %w", err)
		}
	}
	return nil
}

// SetCreator sets value of Creator conditional field.
func (a *AiComposeTone) SetCreator(value bool) {
	if value {
		a.Flags.Set(0)
		a.Creator = true
	} else {
		a.Flags.Unset(0)
		a.Creator = false
	}
}

// GetCreator returns value of Creator conditional field.
func (a *AiComposeTone) GetCreator() (value bool) {
	if a == nil {
		return
	}
	return a.Flags.Has(0)
}

// GetID returns value of ID field.
func (a *AiComposeTone) GetID() (value int64) {
	if a == nil {
		return
	}
	return a.ID
}

// GetAccessHash returns value of AccessHash field.
func (a *AiComposeTone) GetAccessHash() (value int64) {
	if a == nil {
		return
	}
	return a.AccessHash
}

// GetSlug returns value of Slug field.
func (a *AiComposeTone) GetSlug() (value string) {
	if a == nil {
		return
	}
	return a.Slug
}

// GetTitle returns value of Title field.
func (a *AiComposeTone) GetTitle() (value string) {
	if a == nil {
		return
	}
	return a.Title
}

// SetEmojiID sets value of EmojiID conditional field.
func (a *AiComposeTone) SetEmojiID(value int64) {
	a.Flags.Set(1)
	a.EmojiID = value
}

// GetEmojiID returns value of EmojiID conditional field and
// boolean which is true if field was set.
func (a *AiComposeTone) GetEmojiID() (value int64, ok bool) {
	if a == nil {
		return
	}
	if !a.Flags.Has(1) {
		return value, false
	}
	return a.EmojiID, true
}

// SetPrompt sets value of Prompt conditional field.
func (a *AiComposeTone) SetPrompt(value string) {
	a.Flags.Set(4)
	a.Prompt = value
}

// GetPrompt returns value of Prompt conditional field and
// boolean which is true if field was set.
func (a *AiComposeTone) GetPrompt() (value string, ok bool) {
	if a == nil {
		return
	}
	if !a.Flags.Has(4) {
		return value, false
	}
	return a.Prompt, true
}

// SetInstallsCount sets value of InstallsCount conditional field.
func (a *AiComposeTone) SetInstallsCount(value int) {
	a.Flags.Set(2)
	a.InstallsCount = value
}

// GetInstallsCount returns value of InstallsCount conditional field and
// boolean which is true if field was set.
func (a *AiComposeTone) GetInstallsCount() (value int, ok bool) {
	if a == nil {
		return
	}
	if !a.Flags.Has(2) {
		return value, false
	}
	return a.InstallsCount, true
}

// SetAuthorID sets value of AuthorID conditional field.
func (a *AiComposeTone) SetAuthorID(value int64) {
	a.Flags.Set(3)
	a.AuthorID = value
}

// GetAuthorID returns value of AuthorID conditional field and
// boolean which is true if field was set.
func (a *AiComposeTone) GetAuthorID() (value int64, ok bool) {
	if a == nil {
		return
	}
	if !a.Flags.Has(3) {
		return value, false
	}
	return a.AuthorID, true
}

// SetExampleEnglish sets value of ExampleEnglish conditional field.
func (a *AiComposeTone) SetExampleEnglish(value AiComposeToneExample) {
	a.Flags.Set(5)
	a.ExampleEnglish = value
}

// GetExampleEnglish returns value of ExampleEnglish conditional field and
// boolean which is true if field was set.
func (a *AiComposeTone) GetExampleEnglish() (value AiComposeToneExample, ok bool) {
	if a == nil {
		return
	}
	if !a.Flags.Has(5) {
		return value, false
	}
	return a.ExampleEnglish, true
}

// AiComposeToneDefault represents TL type `aiComposeToneDefault#9bad6414`.
//
// See https://core.telegram.org/constructor/aiComposeToneDefault for reference.
type AiComposeToneDefault struct {
	// Tone field of AiComposeToneDefault.
	Tone string
	// EmojiID field of AiComposeToneDefault.
	EmojiID int64
	// Title field of AiComposeToneDefault.
	Title string
}

// AiComposeToneDefaultTypeID is TL type id of AiComposeToneDefault.
const AiComposeToneDefaultTypeID = 0x9bad6414

// construct implements constructor of AiComposeToneClass.
func (a AiComposeToneDefault) construct() AiComposeToneClass { return &a }

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

	_ AiComposeToneClass = &AiComposeToneDefault{}
)

func (a *AiComposeToneDefault) Zero() bool {
	if a == nil {
		return true
	}
	if !(a.Tone == "") {
		return false
	}
	if !(a.EmojiID == 0) {
		return false
	}
	if !(a.Title == "") {
		return false
	}

	return true
}

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

// FillFrom fills AiComposeToneDefault from given interface.
func (a *AiComposeToneDefault) FillFrom(from interface {
	GetTone() (value string)
	GetEmojiID() (value int64)
	GetTitle() (value string)
}) {
	a.Tone = from.GetTone()
	a.EmojiID = from.GetEmojiID()
	a.Title = from.GetTitle()
}

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

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

// TypeInfo returns info about TL type.
func (a *AiComposeToneDefault) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "aiComposeToneDefault",
		ID:   AiComposeToneDefaultTypeID,
	}
	if a == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Tone",
			SchemaName: "tone",
		},
		{
			Name:       "EmojiID",
			SchemaName: "emoji_id",
		},
		{
			Name:       "Title",
			SchemaName: "title",
		},
	}
	return typ
}

// Encode implements bin.Encoder.
func (a *AiComposeToneDefault) Encode(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't encode aiComposeToneDefault#9bad6414 as nil")
	}
	b.PutID(AiComposeToneDefaultTypeID)
	return a.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (a *AiComposeToneDefault) EncodeBare(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't encode aiComposeToneDefault#9bad6414 as nil")
	}
	b.PutString(a.Tone)
	b.PutLong(a.EmojiID)
	b.PutString(a.Title)
	return nil
}

// Decode implements bin.Decoder.
func (a *AiComposeToneDefault) Decode(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't decode aiComposeToneDefault#9bad6414 to nil")
	}
	if err := b.ConsumeID(AiComposeToneDefaultTypeID); err != nil {
		return fmt.Errorf("unable to decode aiComposeToneDefault#9bad6414: %w", err)
	}
	return a.DecodeBare(b)
}

// DecodeBare implements bin.BareDecoder.
func (a *AiComposeToneDefault) DecodeBare(b *bin.Buffer) error {
	if a == nil {
		return fmt.Errorf("can't decode aiComposeToneDefault#9bad6414 to nil")
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeToneDefault#9bad6414: field tone: %w", err)
		}
		a.Tone = value
	}
	{
		value, err := b.Long()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeToneDefault#9bad6414: field emoji_id: %w", err)
		}
		a.EmojiID = value
	}
	{
		value, err := b.String()
		if err != nil {
			return fmt.Errorf("unable to decode aiComposeToneDefault#9bad6414: field title: %w", err)
		}
		a.Title = value
	}
	return nil
}

// GetTone returns value of Tone field.
func (a *AiComposeToneDefault) GetTone() (value string) {
	if a == nil {
		return
	}
	return a.Tone
}

// GetEmojiID returns value of EmojiID field.
func (a *AiComposeToneDefault) GetEmojiID() (value int64) {
	if a == nil {
		return
	}
	return a.EmojiID
}

// GetTitle returns value of Title field.
func (a *AiComposeToneDefault) GetTitle() (value string) {
	if a == nil {
		return
	}
	return a.Title
}

// AiComposeToneClassName is schema name of AiComposeToneClass.
const AiComposeToneClassName = "AiComposeTone"

// AiComposeToneClass represents AiComposeTone generic type.
//
// See https://core.telegram.org/type/AiComposeTone for reference.
//
// Example:
//
//	g, err := tg.DecodeAiComposeTone(buf)
//	if err != nil {
//	    panic(err)
//	}
//	switch v := g.(type) {
//	case *tg.AiComposeTone: // aiComposeTone#cff63ea9
//	case *tg.AiComposeToneDefault: // aiComposeToneDefault#9bad6414
//	default: panic(v)
//	}
type AiComposeToneClass interface {
	bin.Encoder
	bin.Decoder
	bin.BareEncoder
	bin.BareDecoder
	construct() AiComposeToneClass

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

	// Title field of AiComposeTone.
	GetTitle() (value string)
}

// AsInput tries to map AiComposeToneDefault to InputAiComposeToneDefault.
func (a *AiComposeToneDefault) AsInput() *InputAiComposeToneDefault {
	value := new(InputAiComposeToneDefault)
	value.Tone = a.GetTone()

	return value
}

// AsInputAiComposeToneID tries to map AiComposeTone to InputAiComposeToneID.
func (a *AiComposeTone) AsInputAiComposeToneID() *InputAiComposeToneID {
	value := new(InputAiComposeToneID)
	value.ID = a.GetID()
	value.AccessHash = a.GetAccessHash()

	return value
}

// AsInputAiComposeToneSlug tries to map AiComposeTone to InputAiComposeToneSlug.
func (a *AiComposeTone) AsInputAiComposeToneSlug() *InputAiComposeToneSlug {
	value := new(InputAiComposeToneSlug)
	value.Slug = a.GetSlug()

	return value
}

// DecodeAiComposeTone implements binary de-serialization for AiComposeToneClass.
func DecodeAiComposeTone(buf *bin.Buffer) (AiComposeToneClass, error) {
	id, err := buf.PeekID()
	if err != nil {
		return nil, err
	}
	switch id {
	case AiComposeToneTypeID:
		// Decoding aiComposeTone#cff63ea9.
		v := AiComposeTone{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode AiComposeToneClass: %w", err)
		}
		return &v, nil
	case AiComposeToneDefaultTypeID:
		// Decoding aiComposeToneDefault#9bad6414.
		v := AiComposeToneDefault{}
		if err := v.Decode(buf); err != nil {
			return nil, fmt.Errorf("unable to decode AiComposeToneClass: %w", err)
		}
		return &v, nil
	default:
		return nil, fmt.Errorf("unable to decode AiComposeToneClass: %w", bin.NewUnexpectedID(id))
	}
}

// AiComposeTone boxes the AiComposeToneClass providing a helper.
type AiComposeToneBox struct {
	AiComposeTone AiComposeToneClass
}

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

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