// Code generated by sysl DO NOT EDIT.
package petshopmodel

import (
	"encoding/json"

	"github.com/anz-bank/sysl/language/go/pkg/relgom/relgomlib"
	"github.com/arr-ai/frozen"
)

// noKeysAtAllData is the internal representation of a tuple in the model.
type noKeysAtAllData struct {
	name string
	age  *int64
}

// MarshalJSON implements json.Marshaler.
func (d *noKeysAtAllData) MarshalJSON() ([]byte, error) {
	return json.Marshal(struct {
		Name string `json:"name,omitempty"`
		Age  *int64 `json:"age,omitempty"`
	}{Name: d.name, Age: d.age})
}

// UnmarshalJSON implements json.Unmarshaler.
func (d *noKeysAtAllData) UnmarshalJSON(data []byte) error {
	var u struct {
		Name string `json:"name,omitempty"`
		Age  *int64 `json:"age,omitempty"`
	}
	if err := json.Unmarshal(data, &u); err != nil {
		return err
	}
	*d = noKeysAtAllData{name: u.Name, age: u.Age}
	return nil
}

// NoKeysAtAll is the public representation tuple in the model.
type NoKeysAtAll struct {
	data  *noKeysAtAllData
	model PetShopModel
}

// Name gets the name attribute from the NoKeysAtAll.
func (t NoKeysAtAll) Name() string {
	return t.data.name
}

// Age gets the age attribute from the NoKeysAtAll.
func (t NoKeysAtAll) Age() *int64 {
	return t.data.age
}

// NoKeysAtAllBuilder builds an instance of NoKeysAtAll in the model.
type NoKeysAtAllBuilder struct {
	data  noKeysAtAllData
	model PetShopModel
	mask  [1]uint64
	apply func(t *noKeysAtAllData) (frozen.Map, error)
}

// WithName sets the name attribute of the NoKeysAtAllBuilder.
func (b *NoKeysAtAllBuilder) WithName(value string) *NoKeysAtAllBuilder {
	relgomlib.UpdateMaskForFieldButPanicIfAlreadySet(&b.mask[0], (uint64(1) << 0))
	b.data.name = value
	return b
}

// WithAge sets the age attribute of the NoKeysAtAllBuilder.
func (b *NoKeysAtAllBuilder) WithAge(value int64) *NoKeysAtAllBuilder {
	relgomlib.UpdateMaskForFieldButPanicIfAlreadySet(&b.mask[0], (uint64(1) << 1))
	b.data.age = &value
	return b
}

var noKeysAtAllStaticMetadata = &relgomlib.EntityTypeStaticMetadata{PKMask: []uint64{0x0}, RequiredMask: []uint64{0x1}}

// Apply applies the built NoKeysAtAll.
func (b *NoKeysAtAllBuilder) Apply() (PetShopModel, NoKeysAtAll, error) {
	relgomlib.PanicIfRequiredFieldsNotSet(b.mask[:], noKeysAtAllStaticMetadata.RequiredMask, "name,")
	set, err := b.apply(&b.data)
	if err != nil {
		return PetShopModel{}, NoKeysAtAll{}, err
	}
	model := b.model.relations.With(noKeysAtAllKey, noKeysAtAllRelationData{set})
	return PetShopModel{model}, NoKeysAtAll{&b.data, b.model}, nil
}

// noKeysAtAllRelationData represents a set of NoKeysAtAll.
type noKeysAtAllRelationData struct {
	set frozen.Map
}

// Count returns the number of tuples in d.
func (d noKeysAtAllRelationData) Count() int {
	return d.set.Count()
}

// MarshalJSON implements json.Marshaler.
func (d noKeysAtAllRelationData) MarshalJSON() ([]byte, error) {
	a := make([]*noKeysAtAllData, 0, d.set.Count())
	for i := d.set.Range(); i.Next(); {
		a = append(a, i.Value().(*noKeysAtAllData))
	}
	return json.Marshal(a)
}

// UnmarshalJSON implements json.Unmarshaler.
func (d *noKeysAtAllRelationData) UnmarshalJSON(data []byte) error {
	a := []*noKeysAtAllData{}
	if err := json.Unmarshal(data, &a); err != nil {
		return err
	}
	set := frozen.NewMap()
	for i, e := range a {
		set = set.With(i, e)
	}
	*d = noKeysAtAllRelationData{set}
	return nil
}

// NoKeysAtAllRelation represents a set of NoKeysAtAll.
type NoKeysAtAllRelation struct {
	noKeysAtAllRelationData
	model PetShopModel
}

// Iterator returns an iterator over NoKeysAtAll tuples in r.
func (r NoKeysAtAllRelation) Iterator() NoKeysAtAllIterator {
	return &noKeysAtAllIterator{model: r.model, i: r.set.Range()}
}

// noKeysAtAllIterator provides for iteration over a set of noKeysAtAllIterator tuples.
type NoKeysAtAllIterator interface {
	MoveNext() bool
	Current() NoKeysAtAll
}

type noKeysAtAllIterator struct {
	model PetShopModel
	i     *frozen.MapIterator
	t     *NoKeysAtAll
}

// MoveNext implements seq.Setable.
func (i *noKeysAtAllIterator) MoveNext() bool {
	if i.i.Next() {
		i.t = &NoKeysAtAll{data: i.i.Value().(*noKeysAtAllData), model: i.model}
		return true
	}
	return false
}

// Current implements seq.Setable.
func (i *noKeysAtAllIterator) Current() NoKeysAtAll {
	if i.t == nil {
		panic("no current NoKeysAtAll")
	}
	return *i.t
}
