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

// HelpPeerColorOption represents TL type `help.peerColorOption#adec6ebe`.
// Contains info about a color palette »¹.
//
// Links:
//  1. https://core.telegram.org/api/colors
//
// See https://core.telegram.org/constructor/help.peerColorOption for reference.
type HelpPeerColorOption struct {
	// Flags, see TL conditional fields¹
	//
	// Links:
	//  1) https://core.telegram.org/mtproto/TL-combinators#conditional-fields
	Flags bin.Fields
	// Whether this palette should not be displayed as an option to the user when choosing a
	// palette to apply to profile pages or message accents.
	Hidden bool
	// Palette ID.
	ColorID int
	// Light mode palette. Will be empty for IDs 0 to 6 inclusive, in which case a palette
	// containing a single color from the following colors should be used: red, orange,
	// violet, green, cyan, blue, pink for indexes 0 to 6 (i.e. the same colors used for
	// randomized fallback message accent colors¹).
	//
	// Links:
	//  1) https://core.telegram.org/api/colors
	//
	// Use SetColors and GetColors helpers.
	Colors HelpPeerColorSetClass
	// Dark mode palette. Optional, defaults to the palette in colors (or the autogenerated
	// palette for IDs 0 to 6) if absent.
	//
	// Use SetDarkColors and GetDarkColors helpers.
	DarkColors HelpPeerColorSetClass
	// Channels can use this palette only after reaching at least the boost level¹ specified
	// in this field.
	//
	// Links:
	//  1) https://core.telegram.org/api/boost
	//
	// Use SetChannelMinLevel and GetChannelMinLevel helpers.
	ChannelMinLevel int
	// Supergroups can use this palette only after reaching at least the boost level¹
	// specified in this field.
	//
	// Links:
	//  1) https://core.telegram.org/api/boost
	//
	// Use SetGroupMinLevel and GetGroupMinLevel helpers.
	GroupMinLevel int
}

// HelpPeerColorOptionTypeID is TL type id of HelpPeerColorOption.
const HelpPeerColorOptionTypeID = 0xadec6ebe

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

func (p *HelpPeerColorOption) Zero() bool {
	if p == nil {
		return true
	}
	if !(p.Flags.Zero()) {
		return false
	}
	if !(p.Hidden == false) {
		return false
	}
	if !(p.ColorID == 0) {
		return false
	}
	if !(p.Colors == nil) {
		return false
	}
	if !(p.DarkColors == nil) {
		return false
	}
	if !(p.ChannelMinLevel == 0) {
		return false
	}
	if !(p.GroupMinLevel == 0) {
		return false
	}

	return true
}

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

// FillFrom fills HelpPeerColorOption from given interface.
func (p *HelpPeerColorOption) FillFrom(from interface {
	GetHidden() (value bool)
	GetColorID() (value int)
	GetColors() (value HelpPeerColorSetClass, ok bool)
	GetDarkColors() (value HelpPeerColorSetClass, ok bool)
	GetChannelMinLevel() (value int, ok bool)
	GetGroupMinLevel() (value int, ok bool)
}) {
	p.Hidden = from.GetHidden()
	p.ColorID = from.GetColorID()
	if val, ok := from.GetColors(); ok {
		p.Colors = val
	}

	if val, ok := from.GetDarkColors(); ok {
		p.DarkColors = val
	}

	if val, ok := from.GetChannelMinLevel(); ok {
		p.ChannelMinLevel = val
	}

	if val, ok := from.GetGroupMinLevel(); ok {
		p.GroupMinLevel = val
	}

}

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

// TypeName returns name of type in TL schema.
func (*HelpPeerColorOption) TypeName() string {
	return "help.peerColorOption"
}

// TypeInfo returns info about TL type.
func (p *HelpPeerColorOption) TypeInfo() tdp.Type {
	typ := tdp.Type{
		Name: "help.peerColorOption",
		ID:   HelpPeerColorOptionTypeID,
	}
	if p == nil {
		typ.Null = true
		return typ
	}
	typ.Fields = []tdp.Field{
		{
			Name:       "Hidden",
			SchemaName: "hidden",
			Null:       !p.Flags.Has(0),
		},
		{
			Name:       "ColorID",
			SchemaName: "color_id",
		},
		{
			Name:       "Colors",
			SchemaName: "colors",
			Null:       !p.Flags.Has(1),
		},
		{
			Name:       "DarkColors",
			SchemaName: "dark_colors",
			Null:       !p.Flags.Has(2),
		},
		{
			Name:       "ChannelMinLevel",
			SchemaName: "channel_min_level",
			Null:       !p.Flags.Has(3),
		},
		{
			Name:       "GroupMinLevel",
			SchemaName: "group_min_level",
			Null:       !p.Flags.Has(4),
		},
	}
	return typ
}

// SetFlags sets flags for non-zero fields.
func (p *HelpPeerColorOption) SetFlags() {
	if !(p.Hidden == false) {
		p.Flags.Set(0)
	}
	if !(p.Colors == nil) {
		p.Flags.Set(1)
	}
	if !(p.DarkColors == nil) {
		p.Flags.Set(2)
	}
	if !(p.ChannelMinLevel == 0) {
		p.Flags.Set(3)
	}
	if !(p.GroupMinLevel == 0) {
		p.Flags.Set(4)
	}
}

// Encode implements bin.Encoder.
func (p *HelpPeerColorOption) Encode(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode help.peerColorOption#adec6ebe as nil")
	}
	b.PutID(HelpPeerColorOptionTypeID)
	return p.EncodeBare(b)
}

// EncodeBare implements bin.BareEncoder.
func (p *HelpPeerColorOption) EncodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't encode help.peerColorOption#adec6ebe as nil")
	}
	p.SetFlags()
	if err := p.Flags.Encode(b); err != nil {
		return fmt.Errorf("unable to encode help.peerColorOption#adec6ebe: field flags: %w", err)
	}
	b.PutInt(p.ColorID)
	if p.Flags.Has(1) {
		if p.Colors == nil {
			return fmt.Errorf("unable to encode help.peerColorOption#adec6ebe: field colors is nil")
		}
		if err := p.Colors.Encode(b); err != nil {
			return fmt.Errorf("unable to encode help.peerColorOption#adec6ebe: field colors: %w", err)
		}
	}
	if p.Flags.Has(2) {
		if p.DarkColors == nil {
			return fmt.Errorf("unable to encode help.peerColorOption#adec6ebe: field dark_colors is nil")
		}
		if err := p.DarkColors.Encode(b); err != nil {
			return fmt.Errorf("unable to encode help.peerColorOption#adec6ebe: field dark_colors: %w", err)
		}
	}
	if p.Flags.Has(3) {
		b.PutInt(p.ChannelMinLevel)
	}
	if p.Flags.Has(4) {
		b.PutInt(p.GroupMinLevel)
	}
	return nil
}

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

// DecodeBare implements bin.BareDecoder.
func (p *HelpPeerColorOption) DecodeBare(b *bin.Buffer) error {
	if p == nil {
		return fmt.Errorf("can't decode help.peerColorOption#adec6ebe to nil")
	}
	{
		if err := p.Flags.Decode(b); err != nil {
			return fmt.Errorf("unable to decode help.peerColorOption#adec6ebe: field flags: %w", err)
		}
	}
	p.Hidden = p.Flags.Has(0)
	{
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode help.peerColorOption#adec6ebe: field color_id: %w", err)
		}
		p.ColorID = value
	}
	if p.Flags.Has(1) {
		value, err := DecodeHelpPeerColorSet(b)
		if err != nil {
			return fmt.Errorf("unable to decode help.peerColorOption#adec6ebe: field colors: %w", err)
		}
		p.Colors = value
	}
	if p.Flags.Has(2) {
		value, err := DecodeHelpPeerColorSet(b)
		if err != nil {
			return fmt.Errorf("unable to decode help.peerColorOption#adec6ebe: field dark_colors: %w", err)
		}
		p.DarkColors = value
	}
	if p.Flags.Has(3) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode help.peerColorOption#adec6ebe: field channel_min_level: %w", err)
		}
		p.ChannelMinLevel = value
	}
	if p.Flags.Has(4) {
		value, err := b.Int()
		if err != nil {
			return fmt.Errorf("unable to decode help.peerColorOption#adec6ebe: field group_min_level: %w", err)
		}
		p.GroupMinLevel = value
	}
	return nil
}

// SetHidden sets value of Hidden conditional field.
func (p *HelpPeerColorOption) SetHidden(value bool) {
	if value {
		p.Flags.Set(0)
		p.Hidden = true
	} else {
		p.Flags.Unset(0)
		p.Hidden = false
	}
}

// GetHidden returns value of Hidden conditional field.
func (p *HelpPeerColorOption) GetHidden() (value bool) {
	if p == nil {
		return
	}
	return p.Flags.Has(0)
}

// GetColorID returns value of ColorID field.
func (p *HelpPeerColorOption) GetColorID() (value int) {
	if p == nil {
		return
	}
	return p.ColorID
}

// SetColors sets value of Colors conditional field.
func (p *HelpPeerColorOption) SetColors(value HelpPeerColorSetClass) {
	p.Flags.Set(1)
	p.Colors = value
}

// GetColors returns value of Colors conditional field and
// boolean which is true if field was set.
func (p *HelpPeerColorOption) GetColors() (value HelpPeerColorSetClass, ok bool) {
	if p == nil {
		return
	}
	if !p.Flags.Has(1) {
		return value, false
	}
	return p.Colors, true
}

// SetDarkColors sets value of DarkColors conditional field.
func (p *HelpPeerColorOption) SetDarkColors(value HelpPeerColorSetClass) {
	p.Flags.Set(2)
	p.DarkColors = value
}

// GetDarkColors returns value of DarkColors conditional field and
// boolean which is true if field was set.
func (p *HelpPeerColorOption) GetDarkColors() (value HelpPeerColorSetClass, ok bool) {
	if p == nil {
		return
	}
	if !p.Flags.Has(2) {
		return value, false
	}
	return p.DarkColors, true
}

// SetChannelMinLevel sets value of ChannelMinLevel conditional field.
func (p *HelpPeerColorOption) SetChannelMinLevel(value int) {
	p.Flags.Set(3)
	p.ChannelMinLevel = value
}

// GetChannelMinLevel returns value of ChannelMinLevel conditional field and
// boolean which is true if field was set.
func (p *HelpPeerColorOption) GetChannelMinLevel() (value int, ok bool) {
	if p == nil {
		return
	}
	if !p.Flags.Has(3) {
		return value, false
	}
	return p.ChannelMinLevel, true
}

// SetGroupMinLevel sets value of GroupMinLevel conditional field.
func (p *HelpPeerColorOption) SetGroupMinLevel(value int) {
	p.Flags.Set(4)
	p.GroupMinLevel = value
}

// GetGroupMinLevel returns value of GroupMinLevel conditional field and
// boolean which is true if field was set.
func (p *HelpPeerColorOption) GetGroupMinLevel() (value int, ok bool) {
	if p == nil {
		return
	}
	if !p.Flags.Has(4) {
		return value, false
	}
	return p.GroupMinLevel, true
}
