// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause

// Code generated by tailscale/cmd/viewer; DO NOT EDIT.

package types

import (
	"database/sql"
	jsonv1 "encoding/json"
	"errors"
	"net/netip"
	"time"

	jsonv2 "github.com/go-json-experiment/json"
	"github.com/go-json-experiment/json/jsontext"
	"gorm.io/gorm"
	"tailscale.com/tailcfg"
	"tailscale.com/types/key"
	"tailscale.com/types/views"
)

//go:generate go run tailscale.com/cmd/cloner  -clonefunc=false -type=User,Node,PreAuthKey

// View returns a read-only view of User.
func (p *User) View() UserView {
	return UserView{ж: p}
}

// UserView provides a read-only view over User.
//
// Its methods should only be called if `Valid()` returns true.
type UserView struct {
	// ж is the underlying mutable value, named with a hard-to-type
	// character that looks pointy like a pointer.
	// It is named distinctively to make you think of how dangerous it is to escape
	// to callers. You must not let callers be able to mutate it.
	ж *User
}

// Valid reports whether v's underlying value is non-nil.
func (v UserView) Valid() bool { return v.ж != nil }

// AsStruct returns a clone of the underlying value which aliases no memory with
// the original.
func (v UserView) AsStruct() *User {
	if v.ж == nil {
		return nil
	}
	return v.ж.Clone()
}

// MarshalJSON implements [jsonv1.Marshaler].
func (v UserView) MarshalJSON() ([]byte, error) {
	return jsonv1.Marshal(v.ж)
}

// MarshalJSONTo implements [jsonv2.MarshalerTo].
func (v UserView) MarshalJSONTo(enc *jsontext.Encoder) error {
	return jsonv2.MarshalEncode(enc, v.ж)
}

// UnmarshalJSON implements [jsonv1.Unmarshaler].
func (v *UserView) UnmarshalJSON(b []byte) error {
	if v.ж != nil {
		return errors.New("already initialized")
	}
	if len(b) == 0 {
		return nil
	}
	var x User
	if err := jsonv1.Unmarshal(b, &x); err != nil {
		return err
	}
	v.ж = &x
	return nil
}

// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
func (v *UserView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
	if v.ж != nil {
		return errors.New("already initialized")
	}
	var x User
	if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
		return err
	}
	v.ж = &x
	return nil
}

func (v UserView) Model() gorm.Model { return v.ж.Model }

// Name (username) for the user, is used if email is empty
// Should not be used, please use Username().
// It is unique if ProviderIdentifier is not set.
func (v UserView) Name() string { return v.ж.Name }

// Typically the full name of the user
func (v UserView) DisplayName() string { return v.ж.DisplayName }

// Email of the user
// Should not be used, please use Username().
func (v UserView) Email() string { return v.ж.Email }

// ProviderIdentifier is a unique or not set identifier of the
// user from OIDC. It is the combination of `iss`
// and `sub` claim in the OIDC token.
// It is unique if set.
// It is unique together with Name.
func (v UserView) ProviderIdentifier() sql.NullString { return v.ж.ProviderIdentifier }

// Provider is the origin of the user account,
// same as RegistrationMethod, without authkey.
func (v UserView) Provider() string      { return v.ж.Provider }
func (v UserView) ProfilePicURL() string { return v.ж.ProfilePicURL }

// A compilation failure here means this code must be regenerated, with the command at the top of this file.
var _UserViewNeedsRegeneration = User(struct {
	gorm.Model
	Name               string
	DisplayName        string
	Email              string
	ProviderIdentifier sql.NullString
	Provider           string
	ProfilePicURL      string
}{})

// View returns a read-only view of Node.
func (p *Node) View() NodeView {
	return NodeView{ж: p}
}

// NodeView provides a read-only view over Node.
//
// Its methods should only be called if `Valid()` returns true.
type NodeView struct {
	// ж is the underlying mutable value, named with a hard-to-type
	// character that looks pointy like a pointer.
	// It is named distinctively to make you think of how dangerous it is to escape
	// to callers. You must not let callers be able to mutate it.
	ж *Node
}

// Valid reports whether v's underlying value is non-nil.
func (v NodeView) Valid() bool { return v.ж != nil }

// AsStruct returns a clone of the underlying value which aliases no memory with
// the original.
func (v NodeView) AsStruct() *Node {
	if v.ж == nil {
		return nil
	}
	return v.ж.Clone()
}

// MarshalJSON implements [jsonv1.Marshaler].
func (v NodeView) MarshalJSON() ([]byte, error) {
	return jsonv1.Marshal(v.ж)
}

// MarshalJSONTo implements [jsonv2.MarshalerTo].
func (v NodeView) MarshalJSONTo(enc *jsontext.Encoder) error {
	return jsonv2.MarshalEncode(enc, v.ж)
}

// UnmarshalJSON implements [jsonv1.Unmarshaler].
func (v *NodeView) UnmarshalJSON(b []byte) error {
	if v.ж != nil {
		return errors.New("already initialized")
	}
	if len(b) == 0 {
		return nil
	}
	var x Node
	if err := jsonv1.Unmarshal(b, &x); err != nil {
		return err
	}
	v.ж = &x
	return nil
}

// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
func (v *NodeView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
	if v.ж != nil {
		return errors.New("already initialized")
	}
	var x Node
	if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
		return err
	}
	v.ж = &x
	return nil
}

func (v NodeView) ID() NodeID                             { return v.ж.ID }
func (v NodeView) MachineKey() key.MachinePublic          { return v.ж.MachineKey }
func (v NodeView) NodeKey() key.NodePublic                { return v.ж.NodeKey }
func (v NodeView) DiscoKey() key.DiscoPublic              { return v.ж.DiscoKey }
func (v NodeView) Endpoints() views.Slice[netip.AddrPort] { return views.SliceOf(v.ж.Endpoints) }
func (v NodeView) Hostinfo() tailcfg.HostinfoView         { return v.ж.Hostinfo.View() }
func (v NodeView) IPv4() views.ValuePointer[netip.Addr]   { return views.ValuePointerOf(v.ж.IPv4) }

func (v NodeView) IPv6() views.ValuePointer[netip.Addr] { return views.ValuePointerOf(v.ж.IPv6) }

// Hostname represents the name given by the Tailscale
// client during registration
func (v NodeView) Hostname() string { return v.ж.Hostname }

// Givenname represents either:
// a DNS normalized version of Hostname
// a valid name set by the User
//
// GivenName is the name used in all DNS related
// parts of headscale.
func (v NodeView) GivenName() string { return v.ж.GivenName }

// UserID is set for ALL nodes (tagged and user-owned) to track "created by".
// For tagged nodes, this is informational only - the tag is the owner.
// For user-owned nodes, this identifies the owner.
// Only nil for orphaned nodes (should not happen in normal operation).
func (v NodeView) UserID() views.ValuePointer[uint] { return views.ValuePointerOf(v.ж.UserID) }

func (v NodeView) User() UserView         { return v.ж.User.View() }
func (v NodeView) RegisterMethod() string { return v.ж.RegisterMethod }

// Tags is the definitive owner for tagged nodes.
// When non-empty, the node is "tagged" and tags define its identity.
// Empty for user-owned nodes.
// Tags cannot be removed once set (one-way transition).
func (v NodeView) Tags() views.Slice[string] { return views.SliceOf(v.ж.Tags) }

// When a node has been created with a PreAuthKey, we need to
// prevent the preauthkey from being deleted before the node.
// The preauthkey can define "tags" of the node so we need it
// around.
func (v NodeView) AuthKeyID() views.ValuePointer[uint64] { return views.ValuePointerOf(v.ж.AuthKeyID) }

func (v NodeView) AuthKey() PreAuthKeyView               { return v.ж.AuthKey.View() }
func (v NodeView) Expiry() views.ValuePointer[time.Time] { return views.ValuePointerOf(v.ж.Expiry) }

// LastSeen is when the node was last in contact with
// headscale. It is best effort and not persisted.
func (v NodeView) LastSeen() views.ValuePointer[time.Time] {
	return views.ValuePointerOf(v.ж.LastSeen)
}

// ApprovedRoutes is a list of routes that the node is allowed to announce
// as a subnet router. They are not necessarily the routes that the node
// announces at the moment.
// See [Node.Hostinfo]
func (v NodeView) ApprovedRoutes() views.Slice[netip.Prefix] {
	return views.SliceOf(v.ж.ApprovedRoutes)
}
func (v NodeView) CreatedAt() time.Time { return v.ж.CreatedAt }
func (v NodeView) UpdatedAt() time.Time { return v.ж.UpdatedAt }
func (v NodeView) DeletedAt() views.ValuePointer[time.Time] {
	return views.ValuePointerOf(v.ж.DeletedAt)
}

func (v NodeView) IsOnline() views.ValuePointer[bool] { return views.ValuePointerOf(v.ж.IsOnline) }

func (v NodeView) String() string { return v.ж.String() }

// A compilation failure here means this code must be regenerated, with the command at the top of this file.
var _NodeViewNeedsRegeneration = Node(struct {
	ID             NodeID
	MachineKey     key.MachinePublic
	NodeKey        key.NodePublic
	DiscoKey       key.DiscoPublic
	Endpoints      []netip.AddrPort
	Hostinfo       *tailcfg.Hostinfo
	IPv4           *netip.Addr
	IPv6           *netip.Addr
	Hostname       string
	GivenName      string
	UserID         *uint
	User           *User
	RegisterMethod string
	Tags           []string
	AuthKeyID      *uint64
	AuthKey        *PreAuthKey
	Expiry         *time.Time
	LastSeen       *time.Time
	ApprovedRoutes []netip.Prefix
	CreatedAt      time.Time
	UpdatedAt      time.Time
	DeletedAt      *time.Time
	IsOnline       *bool
}{})

// View returns a read-only view of PreAuthKey.
func (p *PreAuthKey) View() PreAuthKeyView {
	return PreAuthKeyView{ж: p}
}

// PreAuthKeyView provides a read-only view over PreAuthKey.
//
// Its methods should only be called if `Valid()` returns true.
type PreAuthKeyView struct {
	// ж is the underlying mutable value, named with a hard-to-type
	// character that looks pointy like a pointer.
	// It is named distinctively to make you think of how dangerous it is to escape
	// to callers. You must not let callers be able to mutate it.
	ж *PreAuthKey
}

// Valid reports whether v's underlying value is non-nil.
func (v PreAuthKeyView) Valid() bool { return v.ж != nil }

// AsStruct returns a clone of the underlying value which aliases no memory with
// the original.
func (v PreAuthKeyView) AsStruct() *PreAuthKey {
	if v.ж == nil {
		return nil
	}
	return v.ж.Clone()
}

// MarshalJSON implements [jsonv1.Marshaler].
func (v PreAuthKeyView) MarshalJSON() ([]byte, error) {
	return jsonv1.Marshal(v.ж)
}

// MarshalJSONTo implements [jsonv2.MarshalerTo].
func (v PreAuthKeyView) MarshalJSONTo(enc *jsontext.Encoder) error {
	return jsonv2.MarshalEncode(enc, v.ж)
}

// UnmarshalJSON implements [jsonv1.Unmarshaler].
func (v *PreAuthKeyView) UnmarshalJSON(b []byte) error {
	if v.ж != nil {
		return errors.New("already initialized")
	}
	if len(b) == 0 {
		return nil
	}
	var x PreAuthKey
	if err := jsonv1.Unmarshal(b, &x); err != nil {
		return err
	}
	v.ж = &x
	return nil
}

// UnmarshalJSONFrom implements [jsonv2.UnmarshalerFrom].
func (v *PreAuthKeyView) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
	if v.ж != nil {
		return errors.New("already initialized")
	}
	var x PreAuthKey
	if err := jsonv2.UnmarshalDecode(dec, &x); err != nil {
		return err
	}
	v.ж = &x
	return nil
}

func (v PreAuthKeyView) ID() uint64 { return v.ж.ID }

// Legacy plaintext key (for backwards compatibility)
func (v PreAuthKeyView) Key() string { return v.ж.Key }

// New bcrypt-based authentication
func (v PreAuthKeyView) Prefix() string { return v.ж.Prefix }

// bcrypt
func (v PreAuthKeyView) Hash() views.ByteSlice[[]byte] { return views.ByteSliceOf(v.ж.Hash) }

// For tagged keys: UserID tracks who created the key (informational)
// For user-owned keys: UserID tracks the node owner
// Can be nil for system-created tagged keys
func (v PreAuthKeyView) UserID() views.ValuePointer[uint] { return views.ValuePointerOf(v.ж.UserID) }

func (v PreAuthKeyView) User() UserView  { return v.ж.User.View() }
func (v PreAuthKeyView) Reusable() bool  { return v.ж.Reusable }
func (v PreAuthKeyView) Ephemeral() bool { return v.ж.Ephemeral }
func (v PreAuthKeyView) Used() bool      { return v.ж.Used }

// Tags to assign to nodes registered with this key.
// Tags are copied to the node during registration.
// If non-empty, this creates tagged nodes (not user-owned).
func (v PreAuthKeyView) Tags() views.Slice[string] { return views.SliceOf(v.ж.Tags) }
func (v PreAuthKeyView) CreatedAt() views.ValuePointer[time.Time] {
	return views.ValuePointerOf(v.ж.CreatedAt)
}

func (v PreAuthKeyView) Expiration() views.ValuePointer[time.Time] {
	return views.ValuePointerOf(v.ж.Expiration)
}

// A compilation failure here means this code must be regenerated, with the command at the top of this file.
var _PreAuthKeyViewNeedsRegeneration = PreAuthKey(struct {
	ID         uint64
	Key        string
	Prefix     string
	Hash       []byte
	UserID     *uint
	User       *User
	Reusable   bool
	Ephemeral  bool
	Used       bool
	Tags       []string
	CreatedAt  *time.Time
	Expiration *time.Time
}{})
