syntax = "proto3";

package rolodex_dns;

option go_package = "gitea.com/town-os/rolodex-dns/go/rolodexdnspb";

// RecordType enumerates the supported DNS record types.
enum RecordType {
  // A record - IPv4 address mapping
  A = 0;
  // AAAA record - IPv6 address mapping
  AAAA = 1;
  // CNAME record - canonical name alias
  CNAME = 2;
  // MX record - mail exchange
  MX = 3;
  // TXT record - text record
  TXT = 4;
  // NS record - name server
  NS = 5;
  // SOA record - start of authority
  SOA = 6;
  // SRV record - service locator
  SRV = 7;
  // PTR record - pointer for reverse DNS
  PTR = 8;
  // URI record - Uniform Resource Identifier (RFC 7553)
  URI = 9;
  // SSHFP record - SSH fingerprint (RFC 4255)
  SSHFP = 10;
  // DNAME record - delegation name (RFC 6672)
  DNAME = 11;
  // ANAME record - alias name (resolved at query time)
  ANAME = 12;
  // ZONEMD record - zone message digest (RFC 9156)
  ZONEMD = 13;
  // TLSA record - TLS authentication (RFC 6698)
  TLSA = 14;
  // DNSKEY record - DNSSEC public key
  DNSKEY = 15;
  // DS record - delegation signer
  DS = 16;
  // RRSIG record - DNSSEC signature
  RRSIG = 17;
  // NSEC record - next secure (DNSSEC)
  NSEC = 18;
  // NSEC3 record - next secure v3 (DNSSEC)
  NSEC3 = 19;
  // NSEC3PARAM record - NSEC3 parameters (DNSSEC)
  NSEC3PARAM = 20;
  // CERT record - certificate storage in DNS (RFC 4398)
  CERT = 21;
}

// DnsRecord represents a single DNS record in the database.
message DnsRecord {
  // Fully qualified domain name (e.g. "example.com.")
  string name = 1;
  // The type of DNS record
  RecordType record_type = 2;
  // The record data (e.g. IP address, hostname, etc.)
  string value = 3;
  // Time-to-live in seconds (default: 300)
  uint32 ttl = 4;
  // Priority for MX and SRV records (ignored for other types)
  uint32 priority = 5;
}

// AddRecordRequest adds a new DNS record to the local database.
message AddRecordRequest {
  // The record to add
  DnsRecord record = 1;
  // Shared secret for authentication (ignored over unix socket)
  string auth_token = 2;
}

// AddRecordResponse is returned after adding a record.
message AddRecordResponse {
  // Whether the operation succeeded
  bool success = 1;
  // Error message if success is false
  string message = 2;
}

// RemoveRecordRequest removes a DNS record from the local database.
message RemoveRecordRequest {
  // Fully qualified domain name to remove records for
  string name = 1;
  // Optional: if set, only remove records of this type. If unset, removes all records for the name.
  RecordType record_type = 2;
  // Optional: if set, only remove the record with this exact value
  string value = 3;
  // Shared secret for authentication
  string auth_token = 4;
}

// RemoveRecordResponse is returned after removing records.
message RemoveRecordResponse {
  // Whether the operation succeeded
  bool success = 1;
  // Number of records removed
  uint32 removed_count = 2;
  // Error message if success is false
  string message = 3;
}

// ListRecordsRequest queries the local DNS database.
message ListRecordsRequest {
  // Optional: filter by domain name (supports wildcard prefix "*.")
  string name_filter = 1;
  // Optional: filter by record type
  RecordType record_type_filter = 2;
  // Whether to apply the record_type_filter
  bool filter_by_type = 3;
  // Shared secret for authentication
  string auth_token = 4;
}

// ListRecordsResponse contains matching DNS records.
message ListRecordsResponse {
  // The matching records
  repeated DnsRecord records = 1;
}

// SetForwarderRequest configures upstream DNS forwarders.
message SetForwarderRequest {
  // List of upstream DNS server addresses (e.g. "8.8.8.8:53")
  repeated string forwarders = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// SetForwarderResponse is returned after setting forwarders.
message SetForwarderResponse {
  // Whether the operation succeeded
  bool success = 1;
  string message = 2;
}

// RblConfig configures a single RBL provider.
message RblConfig {
  // The RBL zone to query (e.g. "zen.spamhaus.org")
  string zone = 1;
  // Whether this RBL is enabled (default: true when added)
  bool enabled = 2;
}

// SetRblConfigRequest configures RBL providers.
message SetRblConfigRequest {
  // The list of RBL providers to use
  repeated RblConfig providers = 1;
  // Whether RBL checking is globally enabled
  bool enabled = 2;
  // Shared secret for authentication
  string auth_token = 3;
}

// SetRblConfigResponse is returned after configuring RBL.
message SetRblConfigResponse {
  bool success = 1;
  string message = 2;
}

// GetRblConfigRequest retrieves the current RBL configuration.
message GetRblConfigRequest {
  string auth_token = 1;
}

// GetRblConfigResponse contains the current RBL configuration.
message GetRblConfigResponse {
  bool enabled = 1;
  repeated RblConfig providers = 2;
}

// FlushCacheRequest clears the DNS and/or RBL cache.
message FlushCacheRequest {
  // Shared secret for authentication
  string auth_token = 1;
}

// FlushCacheResponse is returned after flushing the cache.
message FlushCacheResponse {
  bool success = 1;
  string message = 2;
}

// NetworkScope defines a DNS view that groups DNS records and associations.
// Each scope has a reserved .home domain used as the default search domain.
message NetworkScope {
  // Unique name for this network scope (e.g. "office", "lab")
  string name = 1;
  // The reserved .home domain for this scope (e.g. "office.home.")
  // If empty on creation, defaults to "<name>.home."
  string home_domain = 2;
}

// CreateNetworkScopeRequest creates a new network scope.
message CreateNetworkScopeRequest {
  // The network scope to create
  NetworkScope scope = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// CreateNetworkScopeResponse is returned after creating a scope.
message CreateNetworkScopeResponse {
  bool success = 1;
  string message = 2;
}

// DeleteNetworkScopeRequest deletes a network scope and all its records and associations.
message DeleteNetworkScopeRequest {
  // Name of the scope to delete
  string name = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// DeleteNetworkScopeResponse is returned after deleting a scope.
message DeleteNetworkScopeResponse {
  bool success = 1;
  string message = 2;
}

// ListNetworkScopesRequest retrieves all network scopes.
message ListNetworkScopesRequest {
  string auth_token = 1;
}

// ListNetworkScopesResponse contains all network scopes.
message ListNetworkScopesResponse {
  repeated NetworkScope scopes = 1;
}

// JoinNetworkRequest associates an IP address with a network scope.
// The association has a TTL that must be refreshed to maintain DNS resolution.
message JoinNetworkRequest {
  // The IP address to associate (e.g. "192.168.1.100")
  string ip_address = 1;
  // The network scope name to join
  string scope_name = 2;
  // TTL in seconds for this association. Must be refreshed before expiry.
  // Default: 300 seconds if set to 0
  uint64 ttl_seconds = 3;
  // Shared secret for authentication
  string auth_token = 4;
}

// JoinNetworkResponse is returned after joining a network.
message JoinNetworkResponse {
  bool success = 1;
  string message = 2;
}

// LeaveNetworkRequest removes an IP address's association with any network scope.
message LeaveNetworkRequest {
  // The IP address to disassociate
  string ip_address = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// LeaveNetworkResponse is returned after leaving a network.
message LeaveNetworkResponse {
  bool success = 1;
  string message = 2;
}

// GetNetworkAssociationsRequest retrieves network associations.
message GetNetworkAssociationsRequest {
  // Optional: filter by scope name. Empty returns all associations.
  string scope_name = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// NetworkAssociation represents a client IP's membership in a network scope.
message NetworkAssociation {
  // The associated IP address
  string ip_address = 1;
  // The network scope name
  string scope_name = 2;
  // TTL in seconds for this association
  uint64 ttl_seconds = 3;
}

// GetNetworkAssociationsResponse contains network associations.
message GetNetworkAssociationsResponse {
  repeated NetworkAssociation associations = 1;
}

// AddScopedRecordRequest adds a DNS record to a specific network scope.
message AddScopedRecordRequest {
  // The network scope name to add the record to
  string scope_name = 1;
  // The DNS record to add
  DnsRecord record = 2;
  // Shared secret for authentication
  string auth_token = 3;
}

// AddScopedRecordResponse is returned after adding a scoped record.
message AddScopedRecordResponse {
  bool success = 1;
  string message = 2;
}

// RemoveScopedRecordRequest removes DNS records from a specific network scope.
message RemoveScopedRecordRequest {
  // The network scope name
  string scope_name = 1;
  // Fully qualified domain name to remove records for
  string name = 2;
  // Optional: record type filter
  RecordType record_type = 3;
  // Optional: exact value filter
  string value = 4;
  // Shared secret for authentication
  string auth_token = 5;
}

// RemoveScopedRecordResponse is returned after removing scoped records.
message RemoveScopedRecordResponse {
  bool success = 1;
  uint32 removed_count = 2;
  string message = 3;
}

// ListScopedRecordsRequest queries DNS records within a network scope.
message ListScopedRecordsRequest {
  // The network scope name
  string scope_name = 1;
  // Optional: filter by domain name (supports wildcard prefix "*.")
  string name_filter = 2;
  // Optional: filter by record type
  RecordType record_type_filter = 3;
  // Whether to apply the record_type_filter
  bool filter_by_type = 4;
  // Shared secret for authentication
  string auth_token = 5;
}

// ListScopedRecordsResponse contains matching scoped DNS records.
message ListScopedRecordsResponse {
  repeated DnsRecord records = 1;
}

// GetSearchDomainsRequest retrieves the search domains for an IP address.
message GetSearchDomainsRequest {
  // The IP address to look up search domains for
  string ip_address = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// GetSearchDomainsResponse contains the search domains for an IP.
message GetSearchDomainsResponse {
  // The search domains (typically the .home domain of the associated scope)
  repeated string search_domains = 1;
}

// AddAuthoritativeZoneRequest declares a zone as authoritative.
message AddAuthoritativeZoneRequest {
  // The zone name (e.g. "example.com.")
  string zone = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// AddAuthoritativeZoneResponse is returned after adding an authoritative zone.
message AddAuthoritativeZoneResponse {
  bool success = 1;
  string message = 2;
}

// RemoveAuthoritativeZoneRequest removes a zone from the authoritative list.
message RemoveAuthoritativeZoneRequest {
  // The zone name to remove
  string zone = 1;
  // Shared secret for authentication
  string auth_token = 2;
}

// RemoveAuthoritativeZoneResponse is returned after removing an authoritative zone.
message RemoveAuthoritativeZoneResponse {
  bool success = 1;
  string message = 2;
}

// ListAuthoritativeZonesRequest retrieves all authoritative zones.
message ListAuthoritativeZonesRequest {
  string auth_token = 1;
}

// ListAuthoritativeZonesResponse contains all authoritative zones.
message ListAuthoritativeZonesResponse {
  repeated string zones = 1;
}

// GetCacheStatsRequest retrieves DNS cache statistics.
message GetCacheStatsRequest {
  string auth_token = 1;
}

// GetCacheStatsResponse contains DNS cache statistics.
message GetCacheStatsResponse {
  uint64 total_entries = 1;
  uint64 hit_count = 2;
  uint64 miss_count = 3;
}

// FlushDnsCacheRequest clears the DNS response cache.
message FlushDnsCacheRequest {
  string auth_token = 1;
}

// FlushDnsCacheResponse is returned after flushing the DNS cache.
message FlushDnsCacheResponse {
  bool success = 1;
  string message = 2;
}

// TtlDriftConfig configures TTL drift adjustment.
message TtlDriftConfig {
  // Mode: "fixed" or "logarithmic"
  string mode = 1;
  // Fixed adjustment string (e.g. "5m", "-30s") for fixed mode
  string fixed_adjustment = 2;
  // Multiplier for logarithmic mode
  double log_multiplier = 3;
}

// SetTtlDriftConfigRequest sets the TTL drift configuration.
message SetTtlDriftConfigRequest {
  TtlDriftConfig config = 1;
  string auth_token = 2;
}

// SetTtlDriftConfigResponse is returned after setting TTL drift config.
message SetTtlDriftConfigResponse {
  bool success = 1;
  string message = 2;
}

// GetTtlDriftConfigRequest retrieves the TTL drift configuration.
message GetTtlDriftConfigRequest {
  string auth_token = 1;
}

// GetTtlDriftConfigResponse contains the TTL drift configuration.
message GetTtlDriftConfigResponse {
  TtlDriftConfig config = 1;
}

// QueryLatencyStat represents latency stats for an upstream server.
message QueryLatencyStat {
  string server = 1;
  double avg_latency_ms = 2;
  uint64 query_count = 3;
}

// GetQueryLatencyStatsRequest retrieves upstream query latency statistics.
message GetQueryLatencyStatsRequest {
  string auth_token = 1;
}

// GetQueryLatencyStatsResponse contains latency statistics.
message GetQueryLatencyStatsResponse {
  repeated QueryLatencyStat stats = 1;
}

// LocalRblEntry represents a local RBL entry.
message LocalRblEntry {
  // The name or IP to block
  string name = 1;
  // Reason for blocking
  string reason = 2;
}

// AddLocalRblEntryRequest adds a local RBL entry.
message AddLocalRblEntryRequest {
  LocalRblEntry entry = 1;
  string auth_token = 2;
}

// AddLocalRblEntryResponse is returned after adding a local RBL entry.
message AddLocalRblEntryResponse {
  bool success = 1;
  string message = 2;
}

// RemoveLocalRblEntryRequest removes a local RBL entry.
message RemoveLocalRblEntryRequest {
  string name = 1;
  string auth_token = 2;
}

// RemoveLocalRblEntryResponse is returned after removing a local RBL entry.
message RemoveLocalRblEntryResponse {
  bool success = 1;
  string message = 2;
}

// ListLocalRblEntriesRequest retrieves all local RBL entries.
message ListLocalRblEntriesRequest {
  string auth_token = 1;
}

// ListLocalRblEntriesResponse contains all local RBL entries.
message ListLocalRblEntriesResponse {
  repeated LocalRblEntry entries = 1;
}

// TlsConfig configures TLS certificate settings.
message TlsConfig {
  string cert_path = 1;
  string key_path = 2;
  bool auto_self_signed = 3;
}

// DotConfig configures DNS-over-TLS.
message DotConfig {
  string bind = 1;
  TlsConfig tls = 2;
}

// SetDotConfigRequest sets the DoT configuration.
message SetDotConfigRequest {
  DotConfig config = 1;
  string auth_token = 2;
}

// SetDotConfigResponse is returned after setting DoT config.
message SetDotConfigResponse {
  bool success = 1;
  string message = 2;
}

// GetDotConfigRequest retrieves the DoT configuration.
message GetDotConfigRequest {
  string auth_token = 1;
}

// GetDotConfigResponse contains the DoT configuration.
message GetDotConfigResponse {
  DotConfig config = 1;
}

// DohConfig configures DNS-over-HTTPS.
message DohConfig {
  string bind = 1;
  TlsConfig tls = 2;
  bool enable_h3 = 3;
}

// SetDohConfigRequest sets the DoH configuration.
message SetDohConfigRequest {
  DohConfig config = 1;
  string auth_token = 2;
}

// SetDohConfigResponse is returned after setting DoH config.
message SetDohConfigResponse {
  bool success = 1;
  string message = 2;
}

// GetDohConfigRequest retrieves the DoH configuration.
message GetDohConfigRequest {
  string auth_token = 1;
}

// GetDohConfigResponse contains the DoH configuration.
message GetDohConfigResponse {
  DohConfig config = 1;
}

// DoqConfig configures DNS-over-QUIC.
message DoqConfig {
  string bind = 1;
  TlsConfig tls = 2;
}

// SetDoqConfigRequest sets the DoQ configuration.
message SetDoqConfigRequest {
  DoqConfig config = 1;
  string auth_token = 2;
}

// SetDoqConfigResponse is returned after setting DoQ config.
message SetDoqConfigResponse {
  bool success = 1;
  string message = 2;
}

// GetDoqConfigRequest retrieves the DoQ configuration.
message GetDoqConfigRequest {
  string auth_token = 1;
}

// GetDoqConfigResponse contains the DoQ configuration.
message GetDoqConfigResponse {
  DoqConfig config = 1;
}

// ProxyConfig configures HTTP proxy for DNS forwarding.
message ProxyConfig {
  // Proxy URL (e.g. "http://proxy:8080")
  string url = 1;
  // Optional proxy authentication ("user:pass")
  string auth = 2;
  // Mode: "connect", "socks5", or "doh"
  string mode = 3;
}

// SetProxyConfigRequest sets the proxy configuration.
message SetProxyConfigRequest {
  ProxyConfig config = 1;
  string auth_token = 2;
}

// SetProxyConfigResponse is returned after setting proxy config.
message SetProxyConfigResponse {
  bool success = 1;
  string message = 2;
}

// GetProxyConfigRequest retrieves the proxy configuration.
message GetProxyConfigRequest {
  string auth_token = 1;
}

// GetProxyConfigResponse contains the proxy configuration.
message GetProxyConfigResponse {
  ProxyConfig config = 1;
}

// DnssecKey represents a DNSSEC signing key.
message DnssecKey {
  int64 id = 1;
  string zone = 2;
  string scope_name = 3;
  string algorithm = 4;
  string key_type = 5;
  uint32 key_tag = 6;
  int64 created_at = 7;
  int64 expires_at = 8;
  bool active = 9;
}

// GenerateDnssecKeyRequest generates a new DNSSEC key pair.
message GenerateDnssecKeyRequest {
  string zone = 1;
  string algorithm = 2;
  string key_type = 3;
  string auth_token = 4;
}

// GenerateDnssecKeyResponse is returned after generating a DNSSEC key.
message GenerateDnssecKeyResponse {
  bool success = 1;
  string message = 2;
  DnssecKey key = 3;
}

// ListDnssecKeysRequest retrieves DNSSEC keys.
message ListDnssecKeysRequest {
  string zone = 1;
  string auth_token = 2;
}

// ListDnssecKeysResponse contains DNSSEC keys.
message ListDnssecKeysResponse {
  repeated DnssecKey keys = 1;
}

// DeleteDnssecKeyRequest deletes a DNSSEC key.
message DeleteDnssecKeyRequest {
  int64 key_id = 1;
  string auth_token = 2;
}

// DeleteDnssecKeyResponse is returned after deleting a key.
message DeleteDnssecKeyResponse {
  bool success = 1;
  string message = 2;
}

// GetDsRecordsRequest retrieves DS records for a zone.
message GetDsRecordsRequest {
  string zone = 1;
  string auth_token = 2;
}

// GetDsRecordsResponse contains DS records.
message GetDsRecordsResponse {
  repeated string ds_records = 1;
}

// SignZoneRequest signs a zone with its DNSSEC keys.
message SignZoneRequest {
  string zone = 1;
  string auth_token = 2;
}

// SignZoneResponse is returned after signing a zone.
message SignZoneResponse {
  bool success = 1;
  string message = 2;
}

// GenerateTlsaRecordRequest generates a TLSA record from a certificate.
message GenerateTlsaRecordRequest {
  string domain = 1;
  uint32 port = 2;
  string protocol = 3;
  uint32 usage = 4;
  uint32 selector = 5;
  uint32 matching_type = 6;
  string cert_pem = 7;
  string auth_token = 8;
}

// GenerateTlsaRecordResponse is returned after generating a TLSA record.
message GenerateTlsaRecordResponse {
  bool success = 1;
  string message = 2;
  string tlsa_record = 3;
}

// ListTlsaRecordsRequest retrieves TLSA records for a domain.
message ListTlsaRecordsRequest {
  string domain = 1;
  string auth_token = 2;
}

// ListTlsaRecordsResponse contains TLSA records.
message ListTlsaRecordsResponse {
  repeated DnsRecord records = 1;
}

// GenerateDaneRootCaRequest generates a DANE root CA.
message GenerateDaneRootCaRequest {
  string name = 1;
  string auth_token = 2;
}

// GenerateDaneRootCaResponse is returned after generating a root CA.
message GenerateDaneRootCaResponse {
  bool success = 1;
  string message = 2;
  string cert_pem = 3;
}

// RequestAcmeCertRequest requests a certificate via ACME DNS-01.
message RequestAcmeCertRequest {
  string domain = 1;
  string provider_url = 2;
  string auth_token = 3;
}

// RequestAcmeCertResponse is returned after requesting an ACME cert.
message RequestAcmeCertResponse {
  bool success = 1;
  string message = 2;
}

// GetAcmeStatusRequest retrieves ACME certificate status.
message GetAcmeStatusRequest {
  string domain = 1;
  string auth_token = 2;
}

// GetAcmeStatusResponse contains ACME certificate status.
message GetAcmeStatusResponse {
  string status = 1;
  int64 expires_at = 2;
  string domain = 3;
}

// ================================================================
// ACME Issuer (CA) Administration
// ================================================================

// EnsureZoneCaRequest ensures a per-zone intermediate CA exists.
message EnsureZoneCaRequest {
  string zone = 1;
  string auth_token = 2;
}

// EnsureZoneCaResponse returns the root and intermediate CA certificates.
message EnsureZoneCaResponse {
  bool success = 1;
  string message = 2;
  string root_ca_pem = 3;
  string intermediate_ca_pem = 4;
}

// CreateEabCredentialRequest mints an EAB credential scoped to a zone.
message CreateEabCredentialRequest {
  string zone = 1;
  string auth_token = 2;
}

// CreateEabCredentialResponse returns the EAB key id and base64url HMAC key.
message CreateEabCredentialResponse {
  bool success = 1;
  string message = 2;
  string kid = 3;
  string hmac_key = 4;
  string directory_url = 5;
}

// RemoveEabCredentialRequest removes an EAB credential by kid.
message RemoveEabCredentialRequest {
  string kid = 1;
  string auth_token = 2;
}

// RemoveEabCredentialResponse is returned after removing an EAB credential.
message RemoveEabCredentialResponse {
  bool success = 1;
  string message = 2;
}

// AcmeAccountInfo describes a registered ACME server account.
message AcmeAccountInfo {
  string account_id = 1;
  string status = 2;
  string zone = 3;
  string eab_kid = 4;
}

// ListAcmeAccountsRequest lists ACME server accounts.
message ListAcmeAccountsRequest {
  string auth_token = 1;
}

// ListAcmeAccountsResponse contains ACME server accounts.
message ListAcmeAccountsResponse {
  repeated AcmeAccountInfo accounts = 1;
}

// AcmeCertificateInfo describes an issued ACME certificate.
message AcmeCertificateInfo {
  int64 id = 1;
  string domain = 2;
  int64 issued_at = 3;
  int64 expires_at = 4;
}

// ListAcmeCertificatesRequest lists issued certificates, optionally by zone.
message ListAcmeCertificatesRequest {
  string zone = 1;
  string auth_token = 2;
}

// ListAcmeCertificatesResponse contains issued ACME certificates.
message ListAcmeCertificatesResponse {
  repeated AcmeCertificateInfo certificates = 1;
}

// Dns64Config configures DNS64 synthesis.
message Dns64Config {
  bool enabled = 1;
  // IPv6 prefix for synthesis (default: "64:ff9b::")
  string prefix = 2;
}

// SetDns64ConfigRequest sets the DNS64 configuration.
message SetDns64ConfigRequest {
  Dns64Config config = 1;
  string auth_token = 2;
}

// SetDns64ConfigResponse is returned after setting DNS64 config.
message SetDns64ConfigResponse {
  bool success = 1;
  string message = 2;
}

// GetDns64ConfigRequest retrieves the DNS64 configuration.
message GetDns64ConfigRequest {
  string auth_token = 1;
}

// GetDns64ConfigResponse contains the DNS64 configuration.
message GetDns64ConfigResponse {
  Dns64Config config = 1;
}

// ================================================================
// DHCP Pool Management
// ================================================================

// DhcpPool represents an IP address pool for DHCP allocation within a scope.
message DhcpPool {
  int64 id = 1;
  string scope_name = 2;
  string range_start = 3;
  string range_end = 4;
  string gateway = 5;
  string subnet_mask = 6;
  string dns_servers = 7;
}

message AddDhcpPoolRequest {
  DhcpPool pool = 1;
  string auth_token = 2;
}

message AddDhcpPoolResponse {
  bool success = 1;
  string message = 2;
}

message RemoveDhcpPoolRequest {
  int64 pool_id = 1;
  string auth_token = 2;
}

message RemoveDhcpPoolResponse {
  bool success = 1;
  string message = 2;
}

message ListDhcpPoolsRequest {
  string scope_name = 1;
  string auth_token = 2;
}

message ListDhcpPoolsResponse {
  repeated DhcpPool pools = 1;
}

// ================================================================
// DHCP Lease Management
// ================================================================

// DhcpLease represents a DHCP lease binding a MAC address to an IP.
message DhcpLease {
  string mac = 1;
  string ip = 2;
  string scope_name = 3;
  string hostname = 4;
  int64 lease_start = 5;
  int64 lease_duration = 6;
  string state = 7;
}

message ListDhcpLeasesRequest {
  string scope_name = 1;
  string auth_token = 2;
}

message ListDhcpLeasesResponse {
  repeated DhcpLease leases = 1;
}

message DeleteDhcpLeaseRequest {
  string mac = 1;
  string auth_token = 2;
}

message DeleteDhcpLeaseResponse {
  bool success = 1;
  string message = 2;
}

// ================================================================
// Per-Scope RBL Providers
// ================================================================

// ScopeRblProvider represents an additional RBL provider for a specific scope.
message ScopeRblProvider {
  string scope_name = 1;
  string zone = 2;
  bool enabled = 3;
}

message AddScopeRblProviderRequest {
  ScopeRblProvider provider = 1;
  string auth_token = 2;
}

message AddScopeRblProviderResponse {
  bool success = 1;
  string message = 2;
}

message RemoveScopeRblProviderRequest {
  string scope_name = 1;
  string zone = 2;
  string auth_token = 3;
}

message RemoveScopeRblProviderResponse {
  bool success = 1;
  string message = 2;
}

message ListScopeRblProvidersRequest {
  string scope_name = 1;
  string auth_token = 2;
}

message ListScopeRblProvidersResponse {
  repeated ScopeRblProvider providers = 1;
}

// ================================================================
// DHCP Certificate Options
// ================================================================

// DhcpCertOption represents a certificate delivered via DHCP options.
message DhcpCertOption {
  string scope_name = 1;
  uint32 option_code = 2;
  bytes cert_data = 3;
  string description = 4;
}

message SetDhcpCertOptionRequest {
  DhcpCertOption option = 1;
  string auth_token = 2;
}

message SetDhcpCertOptionResponse {
  bool success = 1;
  string message = 2;
}

message RemoveDhcpCertOptionRequest {
  string scope_name = 1;
  uint32 option_code = 2;
  string auth_token = 3;
}

message RemoveDhcpCertOptionResponse {
  bool success = 1;
  string message = 2;
}

message ListDhcpCertOptionsRequest {
  string scope_name = 1;
  string auth_token = 2;
}

message ListDhcpCertOptionsResponse {
  repeated DhcpCertOption options = 1;
}

// RolodexDnsService provides the gRPC management interface for rolodex-dns.
//
// All methods accept an auth_token field for shared-secret authentication.
// When connecting over a unix socket, the auth_token is ignored.
service RolodexDnsService {
  // AddRecord adds a DNS record to the local database.
  // Path: /rolodex_dns.RolodexDnsService/AddRecord
  rpc AddRecord(AddRecordRequest) returns (AddRecordResponse);

  // RemoveRecord removes DNS record(s) from the local database.
  // Path: /rolodex_dns.RolodexDnsService/RemoveRecord
  rpc RemoveRecord(RemoveRecordRequest) returns (RemoveRecordResponse);

  // ListRecords queries the local DNS database with optional filters.
  // Path: /rolodex_dns.RolodexDnsService/ListRecords
  rpc ListRecords(ListRecordsRequest) returns (ListRecordsResponse);

  // SetForwarders configures the upstream DNS forwarders.
  // Path: /rolodex_dns.RolodexDnsService/SetForwarders
  rpc SetForwarders(SetForwarderRequest) returns (SetForwarderResponse);

  // SetRblConfig configures RBL (Realtime Blackhole List) settings.
  // Path: /rolodex_dns.RolodexDnsService/SetRblConfig
  rpc SetRblConfig(SetRblConfigRequest) returns (SetRblConfigResponse);

  // GetRblConfig retrieves the current RBL configuration.
  // Path: /rolodex_dns.RolodexDnsService/GetRblConfig
  rpc GetRblConfig(GetRblConfigRequest) returns (GetRblConfigResponse);

  // FlushCache clears DNS and RBL caches.
  // Path: /rolodex_dns.RolodexDnsService/FlushCache
  rpc FlushCache(FlushCacheRequest) returns (FlushCacheResponse);

  // CreateNetworkScope creates a new network scope with a reserved .home domain.
  // Path: /rolodex_dns.RolodexDnsService/CreateNetworkScope
  rpc CreateNetworkScope(CreateNetworkScopeRequest) returns (CreateNetworkScopeResponse);

  // DeleteNetworkScope removes a network scope and all its records and associations.
  // Path: /rolodex_dns.RolodexDnsService/DeleteNetworkScope
  rpc DeleteNetworkScope(DeleteNetworkScopeRequest) returns (DeleteNetworkScopeResponse);

  // ListNetworkScopes retrieves all configured network scopes.
  // Path: /rolodex_dns.RolodexDnsService/ListNetworkScopes
  rpc ListNetworkScopes(ListNetworkScopesRequest) returns (ListNetworkScopesResponse);

  // JoinNetwork associates a client IP address with a network scope.
  // The association has a TTL and must be refreshed regularly.
  // Path: /rolodex_dns.RolodexDnsService/JoinNetwork
  rpc JoinNetwork(JoinNetworkRequest) returns (JoinNetworkResponse);

  // LeaveNetwork removes an IP address's association with its network scope.
  // Path: /rolodex_dns.RolodexDnsService/LeaveNetwork
  rpc LeaveNetwork(LeaveNetworkRequest) returns (LeaveNetworkResponse);

  // GetNetworkAssociations retrieves IP-to-scope associations.
  // Path: /rolodex_dns.RolodexDnsService/GetNetworkAssociations
  rpc GetNetworkAssociations(GetNetworkAssociationsRequest) returns (GetNetworkAssociationsResponse);

  // AddScopedRecord adds a DNS record within a specific network scope.
  // Path: /rolodex_dns.RolodexDnsService/AddScopedRecord
  rpc AddScopedRecord(AddScopedRecordRequest) returns (AddScopedRecordResponse);

  // RemoveScopedRecord removes DNS records from a specific network scope.
  // Path: /rolodex_dns.RolodexDnsService/RemoveScopedRecord
  rpc RemoveScopedRecord(RemoveScopedRecordRequest) returns (RemoveScopedRecordResponse);

  // ListScopedRecords queries DNS records within a network scope.
  // Path: /rolodex_dns.RolodexDnsService/ListScopedRecords
  rpc ListScopedRecords(ListScopedRecordsRequest) returns (ListScopedRecordsResponse);

  // GetSearchDomains retrieves the search domains for a client IP address.
  // Path: /rolodex_dns.RolodexDnsService/GetSearchDomains
  rpc GetSearchDomains(GetSearchDomainsRequest) returns (GetSearchDomainsResponse);

  // AddAuthoritativeZone declares a zone as authoritative.
  // Path: /rolodex_dns.RolodexDnsService/AddAuthoritativeZone
  rpc AddAuthoritativeZone(AddAuthoritativeZoneRequest) returns (AddAuthoritativeZoneResponse);

  // RemoveAuthoritativeZone removes a zone from the authoritative list.
  // Path: /rolodex_dns.RolodexDnsService/RemoveAuthoritativeZone
  rpc RemoveAuthoritativeZone(RemoveAuthoritativeZoneRequest) returns (RemoveAuthoritativeZoneResponse);

  // ListAuthoritativeZones retrieves all authoritative zones.
  // Path: /rolodex_dns.RolodexDnsService/ListAuthoritativeZones
  rpc ListAuthoritativeZones(ListAuthoritativeZonesRequest) returns (ListAuthoritativeZonesResponse);

  // GetCacheStats retrieves DNS cache statistics.
  // Path: /rolodex_dns.RolodexDnsService/GetCacheStats
  rpc GetCacheStats(GetCacheStatsRequest) returns (GetCacheStatsResponse);

  // FlushDnsCache clears the DNS response cache.
  // Path: /rolodex_dns.RolodexDnsService/FlushDnsCache
  rpc FlushDnsCache(FlushDnsCacheRequest) returns (FlushDnsCacheResponse);

  // SetTtlDriftConfig sets the TTL drift configuration.
  // Path: /rolodex_dns.RolodexDnsService/SetTtlDriftConfig
  rpc SetTtlDriftConfig(SetTtlDriftConfigRequest) returns (SetTtlDriftConfigResponse);

  // GetTtlDriftConfig retrieves the TTL drift configuration.
  // Path: /rolodex_dns.RolodexDnsService/GetTtlDriftConfig
  rpc GetTtlDriftConfig(GetTtlDriftConfigRequest) returns (GetTtlDriftConfigResponse);

  // GetQueryLatencyStats retrieves upstream query latency statistics.
  // Path: /rolodex_dns.RolodexDnsService/GetQueryLatencyStats
  rpc GetQueryLatencyStats(GetQueryLatencyStatsRequest) returns (GetQueryLatencyStatsResponse);

  // AddLocalRblEntry adds a local RBL entry.
  // Path: /rolodex_dns.RolodexDnsService/AddLocalRblEntry
  rpc AddLocalRblEntry(AddLocalRblEntryRequest) returns (AddLocalRblEntryResponse);

  // RemoveLocalRblEntry removes a local RBL entry.
  // Path: /rolodex_dns.RolodexDnsService/RemoveLocalRblEntry
  rpc RemoveLocalRblEntry(RemoveLocalRblEntryRequest) returns (RemoveLocalRblEntryResponse);

  // ListLocalRblEntries retrieves all local RBL entries.
  // Path: /rolodex_dns.RolodexDnsService/ListLocalRblEntries
  rpc ListLocalRblEntries(ListLocalRblEntriesRequest) returns (ListLocalRblEntriesResponse);

  // SetDotConfig sets the DNS-over-TLS configuration.
  // Path: /rolodex_dns.RolodexDnsService/SetDotConfig
  rpc SetDotConfig(SetDotConfigRequest) returns (SetDotConfigResponse);

  // GetDotConfig retrieves the DNS-over-TLS configuration.
  // Path: /rolodex_dns.RolodexDnsService/GetDotConfig
  rpc GetDotConfig(GetDotConfigRequest) returns (GetDotConfigResponse);

  // SetDohConfig sets the DNS-over-HTTPS configuration.
  // Path: /rolodex_dns.RolodexDnsService/SetDohConfig
  rpc SetDohConfig(SetDohConfigRequest) returns (SetDohConfigResponse);

  // GetDohConfig retrieves the DNS-over-HTTPS configuration.
  // Path: /rolodex_dns.RolodexDnsService/GetDohConfig
  rpc GetDohConfig(GetDohConfigRequest) returns (GetDohConfigResponse);

  // SetDoqConfig sets the DNS-over-QUIC configuration.
  // Path: /rolodex_dns.RolodexDnsService/SetDoqConfig
  rpc SetDoqConfig(SetDoqConfigRequest) returns (SetDoqConfigResponse);

  // GetDoqConfig retrieves the DNS-over-QUIC configuration.
  // Path: /rolodex_dns.RolodexDnsService/GetDoqConfig
  rpc GetDoqConfig(GetDoqConfigRequest) returns (GetDoqConfigResponse);

  // SetProxyConfig sets the HTTP proxy configuration.
  // Path: /rolodex_dns.RolodexDnsService/SetProxyConfig
  rpc SetProxyConfig(SetProxyConfigRequest) returns (SetProxyConfigResponse);

  // GetProxyConfig retrieves the HTTP proxy configuration.
  // Path: /rolodex_dns.RolodexDnsService/GetProxyConfig
  rpc GetProxyConfig(GetProxyConfigRequest) returns (GetProxyConfigResponse);

  // GenerateDnssecKey generates a new DNSSEC key pair for a zone.
  // Path: /rolodex_dns.RolodexDnsService/GenerateDnssecKey
  rpc GenerateDnssecKey(GenerateDnssecKeyRequest) returns (GenerateDnssecKeyResponse);

  // ListDnssecKeys retrieves DNSSEC keys for a zone.
  // Path: /rolodex_dns.RolodexDnsService/ListDnssecKeys
  rpc ListDnssecKeys(ListDnssecKeysRequest) returns (ListDnssecKeysResponse);

  // DeleteDnssecKey deletes a DNSSEC key.
  // Path: /rolodex_dns.RolodexDnsService/DeleteDnssecKey
  rpc DeleteDnssecKey(DeleteDnssecKeyRequest) returns (DeleteDnssecKeyResponse);

  // GetDsRecords retrieves DS records for a zone.
  // Path: /rolodex_dns.RolodexDnsService/GetDsRecords
  rpc GetDsRecords(GetDsRecordsRequest) returns (GetDsRecordsResponse);

  // SignZone signs a zone with its DNSSEC keys.
  // Path: /rolodex_dns.RolodexDnsService/SignZone
  rpc SignZone(SignZoneRequest) returns (SignZoneResponse);

  // GenerateTlsaRecord generates a TLSA record from a certificate.
  // Path: /rolodex_dns.RolodexDnsService/GenerateTlsaRecord
  rpc GenerateTlsaRecord(GenerateTlsaRecordRequest) returns (GenerateTlsaRecordResponse);

  // ListTlsaRecords retrieves TLSA records for a domain.
  // Path: /rolodex_dns.RolodexDnsService/ListTlsaRecords
  rpc ListTlsaRecords(ListTlsaRecordsRequest) returns (ListTlsaRecordsResponse);

  // GenerateDaneRootCa generates a DANE root CA certificate.
  // Path: /rolodex_dns.RolodexDnsService/GenerateDaneRootCa
  rpc GenerateDaneRootCa(GenerateDaneRootCaRequest) returns (GenerateDaneRootCaResponse);

  // RequestAcmeCert requests a certificate via ACME DNS-01.
  // Path: /rolodex_dns.RolodexDnsService/RequestAcmeCert
  rpc RequestAcmeCert(RequestAcmeCertRequest) returns (RequestAcmeCertResponse);

  // GetAcmeStatus retrieves ACME certificate status.
  // Path: /rolodex_dns.RolodexDnsService/GetAcmeStatus
  rpc GetAcmeStatus(GetAcmeStatusRequest) returns (GetAcmeStatusResponse);

  // SetDns64Config sets the DNS64 configuration.
  // Path: /rolodex_dns.RolodexDnsService/SetDns64Config
  rpc SetDns64Config(SetDns64ConfigRequest) returns (SetDns64ConfigResponse);

  // GetDns64Config retrieves the DNS64 configuration.
  // Path: /rolodex_dns.RolodexDnsService/GetDns64Config
  rpc GetDns64Config(GetDns64ConfigRequest) returns (GetDns64ConfigResponse);

  // ================================================================
  // DHCP Pool Management
  // ================================================================

  // AddDhcpPool adds an IP address pool for DHCP allocation within a scope.
  rpc AddDhcpPool(AddDhcpPoolRequest) returns (AddDhcpPoolResponse);

  // RemoveDhcpPool removes a DHCP address pool by ID.
  rpc RemoveDhcpPool(RemoveDhcpPoolRequest) returns (RemoveDhcpPoolResponse);

  // ListDhcpPools lists DHCP address pools, optionally filtered by scope.
  rpc ListDhcpPools(ListDhcpPoolsRequest) returns (ListDhcpPoolsResponse);

  // ================================================================
  // DHCP Lease Management
  // ================================================================

  // ListDhcpLeases lists DHCP leases, optionally filtered by scope.
  rpc ListDhcpLeases(ListDhcpLeasesRequest) returns (ListDhcpLeasesResponse);

  // DeleteDhcpLease deletes a DHCP lease by MAC address.
  rpc DeleteDhcpLease(DeleteDhcpLeaseRequest) returns (DeleteDhcpLeaseResponse);

  // ================================================================
  // Per-Scope RBL Providers
  // ================================================================

  // AddScopeRblProvider adds an additional RBL provider for a specific scope.
  rpc AddScopeRblProvider(AddScopeRblProviderRequest) returns (AddScopeRblProviderResponse);

  // RemoveScopeRblProvider removes a scope-specific RBL provider.
  rpc RemoveScopeRblProvider(RemoveScopeRblProviderRequest) returns (RemoveScopeRblProviderResponse);

  // ListScopeRblProviders lists RBL providers for a specific scope.
  rpc ListScopeRblProviders(ListScopeRblProvidersRequest) returns (ListScopeRblProvidersResponse);

  // ================================================================
  // DHCP Certificate Options
  // ================================================================

  // SetDhcpCertOption sets a certificate to be delivered via DHCP for a scope.
  rpc SetDhcpCertOption(SetDhcpCertOptionRequest) returns (SetDhcpCertOptionResponse);

  // RemoveDhcpCertOption removes a DHCP certificate option for a scope.
  rpc RemoveDhcpCertOption(RemoveDhcpCertOptionRequest) returns (RemoveDhcpCertOptionResponse);

  // ListDhcpCertOptions lists DHCP certificate options for a scope.
  rpc ListDhcpCertOptions(ListDhcpCertOptionsRequest) returns (ListDhcpCertOptionsResponse);

  // ================================================================
  // ACME Issuer (CA) Administration
  // ================================================================

  // EnsureZoneCa creates the per-zone intermediate CA if absent and returns the
  // root + intermediate PEM.
  rpc EnsureZoneCa(EnsureZoneCaRequest) returns (EnsureZoneCaResponse);

  // CreateEabCredential mints an External Account Binding (kid + HMAC) scoped to
  // a zone, for use by an ACME client's newAccount.
  rpc CreateEabCredential(CreateEabCredentialRequest) returns (CreateEabCredentialResponse);

  // RemoveEabCredential removes an EAB credential by kid.
  rpc RemoveEabCredential(RemoveEabCredentialRequest) returns (RemoveEabCredentialResponse);

  // ListAcmeAccounts lists registered ACME server accounts.
  rpc ListAcmeAccounts(ListAcmeAccountsRequest) returns (ListAcmeAccountsResponse);

  // ListAcmeCertificates lists issued ACME certificates, optionally by zone.
  rpc ListAcmeCertificates(ListAcmeCertificatesRequest) returns (ListAcmeCertificatesResponse);
}
