// Code generated by ent, DO NOT EDIT.

package ent

import (
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"entgo.io/ent"
	"entgo.io/ent/dialect/sql"
	"github.com/google/uuid"
	"github.com/lightsparkdev/spark/common/keys"
	"github.com/lightsparkdev/spark/so/ent/depositaddress"
	"github.com/lightsparkdev/spark/so/ent/schema/schematype"
	"github.com/lightsparkdev/spark/so/ent/signingkeyshare"
	"github.com/lightsparkdev/spark/so/ent/tree"
)

// DepositAddress is the model entity for the DepositAddress schema.
type DepositAddress struct {
	config `json:"-"`
	// ID of the ent.
	ID uuid.UUID `json:"id,omitempty"`
	// CreateTime holds the value of the "create_time" field.
	CreateTime time.Time `json:"create_time,omitempty"`
	// UpdateTime holds the value of the "update_time" field.
	UpdateTime time.Time `json:"update_time,omitempty"`
	// P2TR address string that pays to the combined public key of SOs and the owner's signing public key.
	Address string `json:"address,omitempty"`
	// Network on which the deposit address is valid.
	Network schematype.Network `json:"network,omitempty"`
	// Identity public key of the owner of the deposit address.
	OwnerIdentityPubkey keys.Public `json:"owner_identity_pubkey,omitempty"`
	// Signing public key of the owner of the deposit address.
	OwnerSigningPubkey keys.Public `json:"owner_signing_pubkey,omitempty"`
	// Height of the block that confirmed the deposit address.
	ConfirmationHeight int64 `json:"confirmation_height,omitempty"`
	// Transaction ID of the block that confirmed the deposit address.
	ConfirmationTxid string `json:"confirmation_txid,omitempty"`
	// Address signatures of the deposit address. It is used prove that all SOs have generated the address.
	AddressSignatures map[string][]uint8 `json:"address_signatures,omitempty"`
	// Proof of keyshare possession signature for the deposit address. It is used to prove that the key used by the coordinator to generate the address is known by all SOs.
	PossessionSignature []byte `json:"possession_signature,omitempty"`
	// Node ID of the deposit address.
	NodeID uuid.UUID `json:"node_id,omitempty"`
	// Whether the deposit address is static.
	IsStatic bool `json:"is_static,omitempty"`
	// Whether the deposit address is the default address for the user.This is only used for static deposit addresses. Static deposit addresses should be unique for the network/user, but since this was not previously enforced, is_default is used to enforce uniqueness.
	IsDefault bool `json:"is_default,omitempty"`
	// Edges holds the relations/edges for other nodes in the graph.
	// The values are being populated by the DepositAddressQuery when eager-loading is set.
	Edges                            DepositAddressEdges `json:"edges"`
	deposit_address_signing_keyshare *uuid.UUID
	selectValues                     sql.SelectValues
}

// DepositAddressEdges holds the relations/edges for other nodes in the graph.
type DepositAddressEdges struct {
	// SigningKeyshare holds the value of the signing_keyshare edge.
	SigningKeyshare *SigningKeyshare `json:"signing_keyshare,omitempty"`
	// Utxo holds the value of the utxo edge.
	Utxo []*Utxo `json:"utxo,omitempty"`
	// Utxoswaps holds the value of the utxoswaps edge.
	Utxoswaps []*UtxoSwap `json:"utxoswaps,omitempty"`
	// Tree holds the value of the tree edge.
	Tree *Tree `json:"tree,omitempty"`
	// loadedTypes holds the information for reporting if a
	// type was loaded (or requested) in eager-loading or not.
	loadedTypes [4]bool
}

// SigningKeyshareOrErr returns the SigningKeyshare value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e DepositAddressEdges) SigningKeyshareOrErr() (*SigningKeyshare, error) {
	if e.SigningKeyshare != nil {
		return e.SigningKeyshare, nil
	} else if e.loadedTypes[0] {
		return nil, &NotFoundError{label: signingkeyshare.Label}
	}
	return nil, &NotLoadedError{edge: "signing_keyshare"}
}

// UtxoOrErr returns the Utxo value or an error if the edge
// was not loaded in eager-loading.
func (e DepositAddressEdges) UtxoOrErr() ([]*Utxo, error) {
	if e.loadedTypes[1] {
		return e.Utxo, nil
	}
	return nil, &NotLoadedError{edge: "utxo"}
}

// UtxoswapsOrErr returns the Utxoswaps value or an error if the edge
// was not loaded in eager-loading.
func (e DepositAddressEdges) UtxoswapsOrErr() ([]*UtxoSwap, error) {
	if e.loadedTypes[2] {
		return e.Utxoswaps, nil
	}
	return nil, &NotLoadedError{edge: "utxoswaps"}
}

// TreeOrErr returns the Tree value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e DepositAddressEdges) TreeOrErr() (*Tree, error) {
	if e.Tree != nil {
		return e.Tree, nil
	} else if e.loadedTypes[3] {
		return nil, &NotFoundError{label: tree.Label}
	}
	return nil, &NotLoadedError{edge: "tree"}
}

// scanValues returns the types for scanning values from sql.Rows.
func (*DepositAddress) scanValues(columns []string) ([]any, error) {
	values := make([]any, len(columns))
	for i := range columns {
		switch columns[i] {
		case depositaddress.FieldAddressSignatures, depositaddress.FieldPossessionSignature:
			values[i] = new([]byte)
		case depositaddress.FieldOwnerIdentityPubkey, depositaddress.FieldOwnerSigningPubkey:
			values[i] = new(keys.Public)
		case depositaddress.FieldIsStatic, depositaddress.FieldIsDefault:
			values[i] = new(sql.NullBool)
		case depositaddress.FieldConfirmationHeight:
			values[i] = new(sql.NullInt64)
		case depositaddress.FieldAddress, depositaddress.FieldNetwork, depositaddress.FieldConfirmationTxid:
			values[i] = new(sql.NullString)
		case depositaddress.FieldCreateTime, depositaddress.FieldUpdateTime:
			values[i] = new(sql.NullTime)
		case depositaddress.FieldID, depositaddress.FieldNodeID:
			values[i] = new(uuid.UUID)
		case depositaddress.ForeignKeys[0]: // deposit_address_signing_keyshare
			values[i] = &sql.NullScanner{S: new(uuid.UUID)}
		default:
			values[i] = new(sql.UnknownType)
		}
	}
	return values, nil
}

// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the DepositAddress fields.
func (da *DepositAddress) assignValues(columns []string, values []any) error {
	if m, n := len(values), len(columns); m < n {
		return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
	}
	for i := range columns {
		switch columns[i] {
		case depositaddress.FieldID:
			if value, ok := values[i].(*uuid.UUID); !ok {
				return fmt.Errorf("unexpected type %T for field id", values[i])
			} else if value != nil {
				da.ID = *value
			}
		case depositaddress.FieldCreateTime:
			if value, ok := values[i].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field create_time", values[i])
			} else if value.Valid {
				da.CreateTime = value.Time
			}
		case depositaddress.FieldUpdateTime:
			if value, ok := values[i].(*sql.NullTime); !ok {
				return fmt.Errorf("unexpected type %T for field update_time", values[i])
			} else if value.Valid {
				da.UpdateTime = value.Time
			}
		case depositaddress.FieldAddress:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field address", values[i])
			} else if value.Valid {
				da.Address = value.String
			}
		case depositaddress.FieldNetwork:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field network", values[i])
			} else if value.Valid {
				da.Network = schematype.Network(value.String)
			}
		case depositaddress.FieldOwnerIdentityPubkey:
			if value, ok := values[i].(*keys.Public); !ok {
				return fmt.Errorf("unexpected type %T for field owner_identity_pubkey", values[i])
			} else if value != nil {
				da.OwnerIdentityPubkey = *value
			}
		case depositaddress.FieldOwnerSigningPubkey:
			if value, ok := values[i].(*keys.Public); !ok {
				return fmt.Errorf("unexpected type %T for field owner_signing_pubkey", values[i])
			} else if value != nil {
				da.OwnerSigningPubkey = *value
			}
		case depositaddress.FieldConfirmationHeight:
			if value, ok := values[i].(*sql.NullInt64); !ok {
				return fmt.Errorf("unexpected type %T for field confirmation_height", values[i])
			} else if value.Valid {
				da.ConfirmationHeight = value.Int64
			}
		case depositaddress.FieldConfirmationTxid:
			if value, ok := values[i].(*sql.NullString); !ok {
				return fmt.Errorf("unexpected type %T for field confirmation_txid", values[i])
			} else if value.Valid {
				da.ConfirmationTxid = value.String
			}
		case depositaddress.FieldAddressSignatures:
			if value, ok := values[i].(*[]byte); !ok {
				return fmt.Errorf("unexpected type %T for field address_signatures", values[i])
			} else if value != nil && len(*value) > 0 {
				if err := json.Unmarshal(*value, &da.AddressSignatures); err != nil {
					return fmt.Errorf("unmarshal field address_signatures: %w", err)
				}
			}
		case depositaddress.FieldPossessionSignature:
			if value, ok := values[i].(*[]byte); !ok {
				return fmt.Errorf("unexpected type %T for field possession_signature", values[i])
			} else if value != nil {
				da.PossessionSignature = *value
			}
		case depositaddress.FieldNodeID:
			if value, ok := values[i].(*uuid.UUID); !ok {
				return fmt.Errorf("unexpected type %T for field node_id", values[i])
			} else if value != nil {
				da.NodeID = *value
			}
		case depositaddress.FieldIsStatic:
			if value, ok := values[i].(*sql.NullBool); !ok {
				return fmt.Errorf("unexpected type %T for field is_static", values[i])
			} else if value.Valid {
				da.IsStatic = value.Bool
			}
		case depositaddress.FieldIsDefault:
			if value, ok := values[i].(*sql.NullBool); !ok {
				return fmt.Errorf("unexpected type %T for field is_default", values[i])
			} else if value.Valid {
				da.IsDefault = value.Bool
			}
		case depositaddress.ForeignKeys[0]:
			if value, ok := values[i].(*sql.NullScanner); !ok {
				return fmt.Errorf("unexpected type %T for field deposit_address_signing_keyshare", values[i])
			} else if value.Valid {
				da.deposit_address_signing_keyshare = new(uuid.UUID)
				*da.deposit_address_signing_keyshare = *value.S.(*uuid.UUID)
			}
		default:
			da.selectValues.Set(columns[i], values[i])
		}
	}
	return nil
}

// Value returns the ent.Value that was dynamically selected and assigned to the DepositAddress.
// This includes values selected through modifiers, order, etc.
func (da *DepositAddress) Value(name string) (ent.Value, error) {
	return da.selectValues.Get(name)
}

// QuerySigningKeyshare queries the "signing_keyshare" edge of the DepositAddress entity.
func (da *DepositAddress) QuerySigningKeyshare() *SigningKeyshareQuery {
	return NewDepositAddressClient(da.config).QuerySigningKeyshare(da)
}

// QueryUtxo queries the "utxo" edge of the DepositAddress entity.
func (da *DepositAddress) QueryUtxo() *UtxoQuery {
	return NewDepositAddressClient(da.config).QueryUtxo(da)
}

// QueryUtxoswaps queries the "utxoswaps" edge of the DepositAddress entity.
func (da *DepositAddress) QueryUtxoswaps() *UtxoSwapQuery {
	return NewDepositAddressClient(da.config).QueryUtxoswaps(da)
}

// QueryTree queries the "tree" edge of the DepositAddress entity.
func (da *DepositAddress) QueryTree() *TreeQuery {
	return NewDepositAddressClient(da.config).QueryTree(da)
}

// Update returns a builder for updating this DepositAddress.
// Note that you need to call DepositAddress.Unwrap() before calling this method if this DepositAddress
// was returned from a transaction, and the transaction was committed or rolled back.
func (da *DepositAddress) Update() *DepositAddressUpdateOne {
	return NewDepositAddressClient(da.config).UpdateOne(da)
}

// Unwrap unwraps the DepositAddress entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (da *DepositAddress) Unwrap() *DepositAddress {
	_tx, ok := da.config.driver.(*txDriver)
	if !ok {
		panic("ent: DepositAddress is not a transactional entity")
	}
	da.config.driver = _tx.drv
	return da
}

// String implements the fmt.Stringer.
func (da *DepositAddress) String() string {
	var builder strings.Builder
	builder.WriteString("DepositAddress(")
	builder.WriteString(fmt.Sprintf("id=%v, ", da.ID))
	builder.WriteString("create_time=")
	builder.WriteString(da.CreateTime.Format(time.ANSIC))
	builder.WriteString(", ")
	builder.WriteString("update_time=")
	builder.WriteString(da.UpdateTime.Format(time.ANSIC))
	builder.WriteString(", ")
	builder.WriteString("address=")
	builder.WriteString(da.Address)
	builder.WriteString(", ")
	builder.WriteString("network=")
	builder.WriteString(fmt.Sprintf("%v", da.Network))
	builder.WriteString(", ")
	builder.WriteString("owner_identity_pubkey=")
	builder.WriteString(fmt.Sprintf("%v", da.OwnerIdentityPubkey))
	builder.WriteString(", ")
	builder.WriteString("owner_signing_pubkey=")
	builder.WriteString(fmt.Sprintf("%v", da.OwnerSigningPubkey))
	builder.WriteString(", ")
	builder.WriteString("confirmation_height=")
	builder.WriteString(fmt.Sprintf("%v", da.ConfirmationHeight))
	builder.WriteString(", ")
	builder.WriteString("confirmation_txid=")
	builder.WriteString(da.ConfirmationTxid)
	builder.WriteString(", ")
	builder.WriteString("address_signatures=")
	builder.WriteString(fmt.Sprintf("%v", da.AddressSignatures))
	builder.WriteString(", ")
	builder.WriteString("possession_signature=")
	builder.WriteString(fmt.Sprintf("%v", da.PossessionSignature))
	builder.WriteString(", ")
	builder.WriteString("node_id=")
	builder.WriteString(fmt.Sprintf("%v", da.NodeID))
	builder.WriteString(", ")
	builder.WriteString("is_static=")
	builder.WriteString(fmt.Sprintf("%v", da.IsStatic))
	builder.WriteString(", ")
	builder.WriteString("is_default=")
	builder.WriteString(fmt.Sprintf("%v", da.IsDefault))
	builder.WriteByte(')')
	return builder.String()
}

// DepositAddresses is a parsable slice of DepositAddress.
type DepositAddresses []*DepositAddress
