// Code generated by node-gen. DO NOT EDIT.
// SPDX-License-Identifier: AGPL-3.0-only

package core

import (
	"fmt"
	"slices"

	"github.com/grafana/mimir/pkg/mimirpb"
	"github.com/grafana/mimir/pkg/streamingpromql/planning"
)

func (a *AggregateExpression) Child(idx int) planning.Node {
	switch idx {
	case 0:
		return a.Inner
	case 1:
		if a.Param == nil {
			panic("cannot get AggregateExpression child at index 1 if Param is nil")
		}
		return a.Param
	default:
		panic(fmt.Sprintf("node of type AggregateExpression supports 2 children, but attempted to get child at index %d", idx))
	}
}

func (a *AggregateExpression) ChildCount() int {
	if a.Param == nil {
		return 1
	}
	return 2
}

func (a *AggregateExpression) SetChildren(children []planning.Node) error {
	switch len(children) {
	case 1:
		a.Inner = children[0]
		a.Param = nil
	case 2:
		a.Inner = children[0]
		a.Param = children[1]
	default:
		return fmt.Errorf("node of type AggregateExpression expects 1 or 2 children, but got %d", len(children))
	}
	return nil
}

func (a *AggregateExpression) ReplaceChild(idx int, node planning.Node) error {
	switch idx {
	case 0:
		a.Inner = node
		return nil
	case 1:
		a.Param = node
		return nil
	default:
		return fmt.Errorf("node of type AggregateExpression supports 2 children, but attempted to replace child at index %d", idx)
	}
}

func (a *AggregateExpression) ChildrenLabels() []string {
	if a.Param == nil {
		return []string{""}
	}
	return []string{"expression", "parameter"}
}

func (a *AggregateExpression) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*AggregateExpression)
	return ok &&
		slices.Equal(a.Grouping, oi.Grouping) &&
		a.Op == oi.Op &&
		a.Without == oi.Without
}

func (b *BinaryExpression) Child(idx int) planning.Node {
	switch idx {
	case 0:
		return b.LHS
	case 1:
		return b.RHS
	default:
		panic(fmt.Sprintf("node of type BinaryExpression supports 2 children, but attempted to get child at index %d", idx))
	}
}

func (b *BinaryExpression) ChildCount() int {
	return 2
}

func (b *BinaryExpression) SetChildren(children []planning.Node) error {
	if len(children) != 2 {
		return fmt.Errorf("node of type BinaryExpression expects 2 children, but got %d", len(children))
	}
	b.LHS = children[0]
	b.RHS = children[1]
	return nil
}

func (b *BinaryExpression) ReplaceChild(idx int, node planning.Node) error {
	switch idx {
	case 0:
		b.LHS = node
		return nil
	case 1:
		b.RHS = node
		return nil
	default:
		return fmt.Errorf("node of type BinaryExpression supports 2 children, but attempted to replace child at index %d", idx)
	}
}

func (b *BinaryExpression) ChildrenLabels() []string {
	return []string{"LHS", "RHS"}
}

func (b *BinaryExpression) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*BinaryExpression)
	return ok &&
		b.Op == oi.Op &&
		b.ReturnBool == oi.ReturnBool &&
		((b.VectorMatching == nil && oi.VectorMatching == nil) || (b.VectorMatching != nil && oi.VectorMatching != nil && genEqualsVectorMatching(*b.VectorMatching, *oi.VectorMatching)))
}

func genEqualsVectorMatchFillValues(a, b VectorMatchFillValues) bool {
	return a.Lhs == b.Lhs &&
		a.LhsSet == b.LhsSet &&
		a.Rhs == b.Rhs &&
		a.RhsSet == b.RhsSet
}

func genEqualsVectorMatching(a, b VectorMatching) bool {
	return a.Card == b.Card &&
		genEqualsVectorMatchFillValues(a.FillValues, b.FillValues) &&
		slices.Equal(a.Include, b.Include) &&
		slices.Equal(a.MatchingLabels, b.MatchingLabels) &&
		a.On == b.On
}

func (d *DataLabelSelector) Child(idx int) planning.Node {
	panic(fmt.Sprintf("node of type DataLabelSelector has no children, but attempted to get child at index %d", idx))
}

func (d *DataLabelSelector) ChildCount() int {
	return 0
}

func (d *DataLabelSelector) SetChildren(children []planning.Node) error {
	if len(children) != 0 {
		return fmt.Errorf("node of type DataLabelSelector expects 0 children, but got %d", len(children))
	}
	return nil
}

func (d *DataLabelSelector) ReplaceChild(idx int, _ planning.Node) error {
	return fmt.Errorf("node of type DataLabelSelector has no children, but attempted to replace child at index %d", idx)
}

func (d *DataLabelSelector) ChildrenLabels() []string {
	return nil
}

func (d *DataLabelSelector) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*DataLabelSelector)
	return ok &&
		slices.EqualFunc(d.Matchers, oi.Matchers, func(a, b *LabelMatcher) bool {
			return ((a == nil && b == nil) || (a != nil && b != nil && genEqualsLabelMatcher(*a, *b)))
		})
}

func genEqualsLabelMatcher(a, b LabelMatcher) bool {
	return a.Name == b.Name &&
		a.Type == b.Type &&
		a.Value == b.Value
}

func (d *DeduplicateAndMerge) Child(idx int) planning.Node {
	if idx != 0 {
		panic(fmt.Sprintf("node of type DeduplicateAndMerge supports 1 child, but attempted to get child at index %d", idx))
	}
	return d.Inner
}

func (d *DeduplicateAndMerge) ChildCount() int {
	return 1
}

func (d *DeduplicateAndMerge) SetChildren(children []planning.Node) error {
	if len(children) != 1 {
		return fmt.Errorf("node of type DeduplicateAndMerge expects one child, but got %d", len(children))
	}
	d.Inner = children[0]
	return nil
}

func (d *DeduplicateAndMerge) ReplaceChild(idx int, node planning.Node) error {
	if idx != 0 {
		return fmt.Errorf("node of type DeduplicateAndMerge supports 1 child, but attempted to replace child at index %d", idx)
	}
	d.Inner = node
	return nil
}

func (d *DeduplicateAndMerge) ChildrenLabels() []string {
	return []string{""}
}

func (d *DeduplicateAndMerge) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	_, ok := other.(*DeduplicateAndMerge)
	return ok
}

func (d *DropName) Child(idx int) planning.Node {
	if idx != 0 {
		panic(fmt.Sprintf("node of type DropName supports 1 child, but attempted to get child at index %d", idx))
	}
	return d.Inner
}

func (d *DropName) ChildCount() int {
	return 1
}

func (d *DropName) SetChildren(children []planning.Node) error {
	if len(children) != 1 {
		return fmt.Errorf("node of type DropName expects one child, but got %d", len(children))
	}
	d.Inner = children[0]
	return nil
}

func (d *DropName) ReplaceChild(idx int, node planning.Node) error {
	if idx != 0 {
		return fmt.Errorf("node of type DropName supports 1 child, but attempted to replace child at index %d", idx)
	}
	d.Inner = node
	return nil
}

func (d *DropName) ChildrenLabels() []string {
	return []string{""}
}

func (d *DropName) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	_, ok := other.(*DropName)
	return ok
}

func (e *EvaluationRoot) Child(idx int) planning.Node {
	if idx != 0 {
		panic(fmt.Sprintf("node of type EvaluationRoot supports 1 child, but attempted to get child at index %d", idx))
	}
	return e.Inner
}

func (e *EvaluationRoot) ChildCount() int {
	return 1
}

func (e *EvaluationRoot) SetChildren(children []planning.Node) error {
	if len(children) != 1 {
		return fmt.Errorf("node of type EvaluationRoot expects one child, but got %d", len(children))
	}
	e.Inner = children[0]
	return nil
}

func (e *EvaluationRoot) ReplaceChild(idx int, node planning.Node) error {
	if idx != 0 {
		return fmt.Errorf("node of type EvaluationRoot supports 1 child, but attempted to replace child at index %d", idx)
	}
	e.Inner = node
	return nil
}

func (e *EvaluationRoot) ChildrenLabels() []string {
	return []string{""}
}

func (e *EvaluationRoot) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	_, ok := other.(*EvaluationRoot)
	return ok
}

func (f *FunctionCall) Child(idx int) planning.Node {
	if idx >= len(f.Args) {
		panic(fmt.Sprintf("this FunctionCall node has %d children, but attempted to get child at index %d", len(f.Args), idx))
	}
	return f.Args[idx]
}

func (f *FunctionCall) ChildCount() int {
	return len(f.Args)
}

func (f *FunctionCall) SetChildren(children []planning.Node) error {
	f.Args = children
	return nil
}

func (f *FunctionCall) ReplaceChild(idx int, node planning.Node) error {
	if idx >= len(f.Args) {
		return fmt.Errorf("this FunctionCall node has %d children, but attempted to replace child at index %d", len(f.Args), idx)
	}
	f.Args[idx] = node
	return nil
}

func (f *FunctionCall) ChildrenLabels() []string {
	switch len(f.Args) {
	case 0:
		return nil
	case 1:
		return []string{""}
	default:
		labels := make([]string, len(f.Args))
		for i := range labels {
			labels[i] = fmt.Sprintf("param %d", i)
		}
		return labels
	}
}

func (f *FunctionCall) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*FunctionCall)
	return ok &&
		slices.EqualFunc(f.AbsentLabels, oi.AbsentLabels, genEqualsLabelAdapter) &&
		f.Function == oi.Function
}

func genEqualsLabelAdapter(a, b mimirpb.LabelAdapter) bool {
	return a.Name == b.Name &&
		a.Value == b.Value
}

func (m *MatrixSelector) Child(idx int) planning.Node {
	panic(fmt.Sprintf("node of type MatrixSelector has no children, but attempted to get child at index %d", idx))
}

func (m *MatrixSelector) ChildCount() int {
	return 0
}

func (m *MatrixSelector) SetChildren(children []planning.Node) error {
	if len(children) != 0 {
		return fmt.Errorf("node of type MatrixSelector expects 0 children, but got %d", len(children))
	}
	return nil
}

func (m *MatrixSelector) ReplaceChild(idx int, _ planning.Node) error {
	return fmt.Errorf("node of type MatrixSelector has no children, but attempted to replace child at index %d", idx)
}

func (m *MatrixSelector) ChildrenLabels() []string {
	return nil
}

func (m *MatrixSelector) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*MatrixSelector)
	return ok &&
		m.Anchored == oi.Anchored &&
		m.AnchoredResetsChanges == oi.AnchoredResetsChanges &&
		m.CounterAware == oi.CounterAware &&
		slices.EqualFunc(m.Matchers, oi.Matchers, func(a, b *LabelMatcher) bool {
			return ((a == nil && b == nil) || (a != nil && b != nil && genEqualsLabelMatcher(*a, *b)))
		}) &&
		m.Offset == oi.Offset &&
		m.Range == oi.Range &&
		m.Smoothed == oi.Smoothed &&
		slices.EqualFunc(m.Subsets, oi.Subsets, genEqualsSubsetMatchers) &&
		((m.Timestamp == nil && oi.Timestamp == nil) || (m.Timestamp != nil && oi.Timestamp != nil && (*m.Timestamp).Equal(*oi.Timestamp)))
}

func genEqualsSubsetMatchers(a, b SubsetMatchers) bool {
	return slices.EqualFunc(a.Matchers, b.Matchers, func(a, b *LabelMatcher) bool {
		return ((a == nil && b == nil) || (a != nil && b != nil && genEqualsLabelMatcher(*a, *b)))
	})
}

func (n *NoOp) Child(idx int) planning.Node {
	panic(fmt.Sprintf("node of type NoOp has no children, but attempted to get child at index %d", idx))
}

func (n *NoOp) ChildCount() int {
	return 0
}

func (n *NoOp) SetChildren(children []planning.Node) error {
	if len(children) != 0 {
		return fmt.Errorf("node of type NoOp expects 0 children, but got %d", len(children))
	}
	return nil
}

func (n *NoOp) ReplaceChild(idx int, _ planning.Node) error {
	return fmt.Errorf("node of type NoOp has no children, but attempted to replace child at index %d", idx)
}

func (n *NoOp) ChildrenLabels() []string {
	return nil
}

func (n *NoOp) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*NoOp)
	return ok &&
		n.MatrixSelector == oi.MatrixSelector
}

func (n *NumberLiteral) Child(idx int) planning.Node {
	panic(fmt.Sprintf("node of type NumberLiteral has no children, but attempted to get child at index %d", idx))
}

func (n *NumberLiteral) ChildCount() int {
	return 0
}

func (n *NumberLiteral) SetChildren(children []planning.Node) error {
	if len(children) != 0 {
		return fmt.Errorf("node of type NumberLiteral expects 0 children, but got %d", len(children))
	}
	return nil
}

func (n *NumberLiteral) ReplaceChild(idx int, _ planning.Node) error {
	return fmt.Errorf("node of type NumberLiteral has no children, but attempted to replace child at index %d", idx)
}

func (n *NumberLiteral) ChildrenLabels() []string {
	return nil
}

func (n *NumberLiteral) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*NumberLiteral)
	return ok &&
		n.Value == oi.Value
}

func (s *StepInvariantExpression) Child(idx int) planning.Node {
	if idx != 0 {
		panic(fmt.Sprintf("node of type StepInvariantExpression supports 1 child, but attempted to get child at index %d", idx))
	}
	return s.Inner
}

func (s *StepInvariantExpression) ChildCount() int {
	return 1
}

func (s *StepInvariantExpression) SetChildren(children []planning.Node) error {
	if len(children) != 1 {
		return fmt.Errorf("node of type StepInvariantExpression expects one child, but got %d", len(children))
	}
	s.Inner = children[0]
	return nil
}

func (s *StepInvariantExpression) ReplaceChild(idx int, node planning.Node) error {
	if idx != 0 {
		return fmt.Errorf("node of type StepInvariantExpression supports 1 child, but attempted to replace child at index %d", idx)
	}
	s.Inner = node
	return nil
}

func (s *StepInvariantExpression) ChildrenLabels() []string {
	return []string{""}
}

func (s *StepInvariantExpression) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	_, ok := other.(*StepInvariantExpression)
	return ok
}

func (s *StringLiteral) Child(idx int) planning.Node {
	panic(fmt.Sprintf("node of type StringLiteral has no children, but attempted to get child at index %d", idx))
}

func (s *StringLiteral) ChildCount() int {
	return 0
}

func (s *StringLiteral) SetChildren(children []planning.Node) error {
	if len(children) != 0 {
		return fmt.Errorf("node of type StringLiteral expects 0 children, but got %d", len(children))
	}
	return nil
}

func (s *StringLiteral) ReplaceChild(idx int, _ planning.Node) error {
	return fmt.Errorf("node of type StringLiteral has no children, but attempted to replace child at index %d", idx)
}

func (s *StringLiteral) ChildrenLabels() []string {
	return nil
}

func (s *StringLiteral) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*StringLiteral)
	return ok &&
		s.Value == oi.Value
}

func (s *Subquery) Child(idx int) planning.Node {
	if idx != 0 {
		panic(fmt.Sprintf("node of type Subquery supports 1 child, but attempted to get child at index %d", idx))
	}
	return s.Inner
}

func (s *Subquery) ChildCount() int {
	return 1
}

func (s *Subquery) SetChildren(children []planning.Node) error {
	if len(children) != 1 {
		return fmt.Errorf("node of type Subquery expects one child, but got %d", len(children))
	}
	s.Inner = children[0]
	return nil
}

func (s *Subquery) ReplaceChild(idx int, node planning.Node) error {
	if idx != 0 {
		return fmt.Errorf("node of type Subquery supports 1 child, but attempted to replace child at index %d", idx)
	}
	s.Inner = node
	return nil
}

func (s *Subquery) ChildrenLabels() []string {
	return []string{""}
}

func (s *Subquery) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*Subquery)
	return ok &&
		s.Offset == oi.Offset &&
		s.Range == oi.Range &&
		s.Step == oi.Step &&
		((s.Timestamp == nil && oi.Timestamp == nil) || (s.Timestamp != nil && oi.Timestamp != nil && (*s.Timestamp).Equal(*oi.Timestamp)))
}

func (u *UnaryExpression) Child(idx int) planning.Node {
	if idx != 0 {
		panic(fmt.Sprintf("node of type UnaryExpression supports 1 child, but attempted to get child at index %d", idx))
	}
	return u.Inner
}

func (u *UnaryExpression) ChildCount() int {
	return 1
}

func (u *UnaryExpression) SetChildren(children []planning.Node) error {
	if len(children) != 1 {
		return fmt.Errorf("node of type UnaryExpression expects one child, but got %d", len(children))
	}
	u.Inner = children[0]
	return nil
}

func (u *UnaryExpression) ReplaceChild(idx int, node planning.Node) error {
	if idx != 0 {
		return fmt.Errorf("node of type UnaryExpression supports 1 child, but attempted to replace child at index %d", idx)
	}
	u.Inner = node
	return nil
}

func (u *UnaryExpression) ChildrenLabels() []string {
	return []string{""}
}

func (u *UnaryExpression) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*UnaryExpression)
	return ok &&
		u.Op == oi.Op
}

func (v *VectorSelector) Child(idx int) planning.Node {
	panic(fmt.Sprintf("node of type VectorSelector has no children, but attempted to get child at index %d", idx))
}

func (v *VectorSelector) ChildCount() int {
	return 0
}

func (v *VectorSelector) SetChildren(children []planning.Node) error {
	if len(children) != 0 {
		return fmt.Errorf("node of type VectorSelector expects 0 children, but got %d", len(children))
	}
	return nil
}

func (v *VectorSelector) ReplaceChild(idx int, _ planning.Node) error {
	return fmt.Errorf("node of type VectorSelector has no children, but attempted to replace child at index %d", idx)
}

func (v *VectorSelector) ChildrenLabels() []string {
	return nil
}

func (v *VectorSelector) EquivalentToIgnoringHintsAndChildren(other planning.Node) bool {
	oi, ok := other.(*VectorSelector)
	return ok &&
		slices.EqualFunc(v.Matchers, oi.Matchers, func(a, b *LabelMatcher) bool {
			return ((a == nil && b == nil) || (a != nil && b != nil && genEqualsLabelMatcher(*a, *b)))
		}) &&
		v.Offset == oi.Offset &&
		v.ReturnSampleTimestamps == oi.ReturnSampleTimestamps &&
		v.ReturnSampleTimestampsPreserveHistograms == oi.ReturnSampleTimestampsPreserveHistograms &&
		v.Smoothed == oi.Smoothed &&
		slices.EqualFunc(v.Subsets, oi.Subsets, genEqualsSubsetMatchers) &&
		((v.Timestamp == nil && oi.Timestamp == nil) || (v.Timestamp != nil && oi.Timestamp != nil && (*v.Timestamp).Equal(*oi.Timestamp)))
}
