// Package database provides SQLite storage for BGP routing data including ASNs,
// prefixes, announcements, peerings, and live route tables.
package database

import (
	"context"
	"time"
)

// Stats contains database statistics including counts for ASNs, prefixes,
// peerings, peers, and live routes, as well as file size and prefix distribution data.
type Stats struct {
	ASNs                   int
	Prefixes               int
	IPv4Prefixes           int
	IPv6Prefixes           int
	Peerings               int
	Peers                  int
	FileSizeBytes          int64
	LiveRoutes             int
	OldestRoute            *time.Time
	NewestRoute            *time.Time
	IPv4PrefixDistribution []PrefixDistribution
	IPv6PrefixDistribution []PrefixDistribution
}

// Store defines the interface for database operations. It provides methods for
// managing ASNs, prefixes, announcements, peerings, BGP peers, and live routes.
// Implementations must be safe for concurrent use.
type Store interface {
	// ASN operations
	GetOrCreateASN(number int, timestamp time.Time) (*ASN, error)
	GetOrCreateASNBatch(asns map[int]time.Time) error

	// Prefix operations
	GetOrCreatePrefix(prefix string, timestamp time.Time) (*Prefix, error)
	UpdatePrefixesBatch(prefixes map[string]time.Time) error

	// Announcement operations
	RecordAnnouncement(announcement *Announcement) error

	// Peering operations
	RecordPeering(asA, asB int, timestamp time.Time) error

	// Statistics
	GetStats() (Stats, error)
	GetStatsContext(ctx context.Context) (Stats, error)

	// Peer operations
	UpdatePeer(peerIP string, peerASN int, messageType string, timestamp time.Time) error
	UpdatePeerBatch(peers map[string]PeerUpdate) error

	// Live route operations
	UpsertLiveRoute(route *LiveRoute) error
	UpsertLiveRouteBatch(routes []*LiveRoute) error
	DeleteLiveRoute(prefix string, originASN int, peerIP string) error
	DeleteLiveRouteBatch(deletions []LiveRouteDeletion) error
	GetPrefixDistribution() (ipv4 []PrefixDistribution, ipv6 []PrefixDistribution, err error)
	GetPrefixDistributionContext(ctx context.Context) (ipv4 []PrefixDistribution, ipv6 []PrefixDistribution, err error)
	GetLiveRouteCounts() (ipv4Count, ipv6Count int, err error)
	GetLiveRouteCountsContext(ctx context.Context) (ipv4Count, ipv6Count int, err error)

	// IP lookup operations
	GetASInfoForIP(ip string) (*ASInfo, error)
	GetASInfoForIPContext(ctx context.Context, ip string) (*ASInfo, error)
	GetIPInfo(ip string) (*IPInfo, error)
	GetIPInfoContext(ctx context.Context, ip string) (*IPInfo, error)

	// ASN WHOIS operations
	GetNextStaleASN(ctx context.Context, staleThreshold time.Duration) (int, error)
	UpdateASNWHOIS(ctx context.Context, update *ASNWHOISUpdate) error
	GetWHOISStats(ctx context.Context, staleThreshold time.Duration) (*WHOISStats, error)

	// AS and prefix detail operations
	GetASDetails(asn int) (*ASN, []LiveRoute, error)
	GetASDetailsContext(ctx context.Context, asn int) (*ASN, []LiveRoute, error)
	GetASPeers(asn int) ([]ASPeer, error)
	GetASPeersContext(ctx context.Context, asn int) ([]ASPeer, error)
	GetPrefixDetails(prefix string) ([]LiveRoute, error)
	GetPrefixDetailsContext(ctx context.Context, prefix string) ([]LiveRoute, error)
	GetRandomPrefixesByLength(maskLength, ipVersion, limit int) ([]LiveRoute, error)
	GetRandomPrefixesByLengthContext(ctx context.Context, maskLength, ipVersion, limit int) ([]LiveRoute, error)

	// Lifecycle
	Close() error

	// Maintenance operations
	Vacuum(ctx context.Context) error
	Analyze(ctx context.Context) error
	Checkpoint(ctx context.Context) error
	Ping(ctx context.Context) error
}

// Ensure Database implements Store
var _ Store = (*Database)(nil)
