syntax = "proto3";

import "google/protobuf/descriptor.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/duration.proto";

option go_package = "/proto";

package daemon;

message EmptyRequest {}

service DaemonService {
  // Login uses setup key to prepare configuration for the daemon.
  rpc Login(LoginRequest) returns (LoginResponse) {}

  // WaitSSOLogin uses the userCode to validate the TokenInfo and
  // waits for the user to continue with the login on a browser
  rpc WaitSSOLogin(WaitSSOLoginRequest) returns (WaitSSOLoginResponse) {}

  // Up starts engine work in the daemon.
  rpc Up(UpRequest) returns (UpResponse) {}

  // Status of the service.
  rpc Status(StatusRequest) returns (StatusResponse) {}

  // Down stops engine work in the daemon.
  rpc Down(DownRequest) returns (DownResponse) {}

  // GetConfig of the daemon.
  rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {}

  // List available networks
  rpc ListNetworks(ListNetworksRequest) returns (ListNetworksResponse) {}

  // Select specific routes
  rpc SelectNetworks(SelectNetworksRequest) returns (SelectNetworksResponse) {}

  // Deselect specific routes
  rpc DeselectNetworks(SelectNetworksRequest) returns (SelectNetworksResponse) {}

  rpc ForwardingRules(EmptyRequest) returns (ForwardingRulesResponse) {}

  // DebugBundle creates a debug bundle
  rpc DebugBundle(DebugBundleRequest) returns (DebugBundleResponse) {}

  // GetLogLevel gets the log level of the daemon
  rpc GetLogLevel(GetLogLevelRequest) returns (GetLogLevelResponse) {}

  // SetLogLevel sets the log level of the daemon
  rpc SetLogLevel(SetLogLevelRequest) returns (SetLogLevelResponse) {}

  // List all states
  rpc ListStates(ListStatesRequest) returns (ListStatesResponse) {}

  // Clean specific state or all states
  rpc CleanState(CleanStateRequest) returns (CleanStateResponse) {}

  // Delete specific state or all states
  rpc DeleteState(DeleteStateRequest) returns (DeleteStateResponse) {}

  // SetSyncResponsePersistence enables or disables sync response persistence
  rpc SetSyncResponsePersistence(SetSyncResponsePersistenceRequest) returns (SetSyncResponsePersistenceResponse) {}

  rpc TracePacket(TracePacketRequest) returns (TracePacketResponse) {}

  rpc SubscribeEvents(SubscribeRequest) returns (stream SystemEvent) {}

  rpc GetEvents(GetEventsRequest) returns (GetEventsResponse) {}

  rpc SwitchProfile(SwitchProfileRequest) returns (SwitchProfileResponse) {}

  rpc SetConfig(SetConfigRequest) returns (SetConfigResponse) {}

  rpc AddProfile(AddProfileRequest) returns (AddProfileResponse) {}

  rpc RemoveProfile(RemoveProfileRequest) returns (RemoveProfileResponse) {}

  rpc ListProfiles(ListProfilesRequest) returns (ListProfilesResponse) {}

  rpc GetActiveProfile(GetActiveProfileRequest) returns (GetActiveProfileResponse) {}

  // Logout disconnects from the network and deletes the peer from the management server
  rpc Logout(LogoutRequest) returns (LogoutResponse) {}

  rpc GetFeatures(GetFeaturesRequest) returns (GetFeaturesResponse) {}

  // GetPeerSSHHostKey retrieves SSH host key for a specific peer
  rpc GetPeerSSHHostKey(GetPeerSSHHostKeyRequest) returns (GetPeerSSHHostKeyResponse) {}

  // RequestJWTAuth initiates JWT authentication flow for SSH
  rpc RequestJWTAuth(RequestJWTAuthRequest) returns (RequestJWTAuthResponse) {}

  // WaitJWTToken waits for JWT authentication completion
  rpc WaitJWTToken(WaitJWTTokenRequest) returns (WaitJWTTokenResponse) {}

// StartCPUProfile starts CPU profiling in the daemon
  rpc StartCPUProfile(StartCPUProfileRequest) returns (StartCPUProfileResponse) {}

  // StopCPUProfile stops CPU profiling in the daemon
  rpc StopCPUProfile(StopCPUProfileRequest) returns (StopCPUProfileResponse) {}

  rpc NotifyOSLifecycle(OSLifecycleRequest) returns(OSLifecycleResponse) {}

  rpc GetInstallerResult(InstallerResultRequest) returns (InstallerResultResponse) {}
}



message OSLifecycleRequest {
  // avoid collision with loglevel enum
  enum CycleType {
    UNKNOWN = 0;
    SLEEP = 1;
    WAKEUP = 2;
  }

  CycleType type = 1;
}

message OSLifecycleResponse {}


message LoginRequest {
  // setupKey netbird setup key.
  string setupKey = 1;

  // This is the old PreSharedKey field which will be deprecated in favor of optionalPreSharedKey field that is defined as optional
  // to allow clearing of preshared key while being able to persist in the config file.
  string preSharedKey = 2 [deprecated = true];

  // managementUrl to authenticate.
  string managementUrl = 3;

  // adminUrl to manage keys.
  string adminURL = 4;

  // natExternalIPs map list of external IPs
  repeated string natExternalIPs = 5;

  // cleanNATExternalIPs clean map list of external IPs.
  // This is needed because the generated code
  // omits initialized empty slices due to omitempty tags
  bool cleanNATExternalIPs = 6;

  bytes customDNSAddress = 7;

  bool isUnixDesktopClient = 8;

  string hostname = 9;

  optional bool rosenpassEnabled = 10;

  optional string interfaceName = 11;

  optional int64 wireguardPort = 12;

  optional string optionalPreSharedKey = 13;

  optional bool disableAutoConnect = 14;

  optional bool serverSSHAllowed = 15;

  optional bool rosenpassPermissive = 16;

  repeated string extraIFaceBlacklist = 17;

  optional bool networkMonitor = 18;

  optional google.protobuf.Duration dnsRouteInterval = 19;

  optional bool disable_client_routes = 20;
  optional bool disable_server_routes = 21;
  optional bool disable_dns = 22;
  optional bool disable_firewall = 23;
  optional bool block_lan_access = 24;

  optional bool disable_notifications = 25;

  repeated string dns_labels = 26;

  // cleanDNSLabels clean map list of DNS labels.
  // This is needed because the generated code
  // omits initialized empty slices due to omitempty tags
  bool cleanDNSLabels = 27;

  optional bool lazyConnectionEnabled = 28;

  optional bool block_inbound = 29;

  optional string profileName = 30;
  optional string username = 31;

  optional int64 mtu = 32;

  // hint is used to pre-fill the email/username field during SSO authentication
  optional string hint = 33;

  optional bool enableSSHRoot = 34;
  optional bool enableSSHSFTP = 35;
  optional bool enableSSHLocalPortForwarding = 36;
  optional bool enableSSHRemotePortForwarding = 37;
  optional bool disableSSHAuth = 38;
  optional int32 sshJWTCacheTTL = 39;
}

message LoginResponse {
  bool   needsSSOLogin = 1;
  string userCode = 2;
  string verificationURI = 3;
  string verificationURIComplete = 4;
}

message WaitSSOLoginRequest {
  string userCode = 1;
  string hostname = 2;
}

message WaitSSOLoginResponse {
  string email = 1;
}

message UpRequest {
  optional string profileName = 1;
  optional string username = 2;
  optional bool autoUpdate = 3;
}

message UpResponse {}

message StatusRequest{
  bool getFullPeerStatus = 1;
  bool shouldRunProbes = 2;
  // the UI do not using this yet, but CLIs could use it to wait until the status is ready
  optional bool waitForReady = 3;
}

message StatusResponse{
  // status of the server.
  string status = 1;
  FullStatus fullStatus = 2;
  // NetBird daemon version
  string daemonVersion = 3;
}

message DownRequest {}

message DownResponse {}

message GetConfigRequest {
  string profileName = 1;
  string username = 2;
}

message GetConfigResponse {
  // managementUrl settings value.
  string managementUrl = 1;

  // configFile settings value.
  string configFile = 2;

  // logFile settings value.
  string logFile = 3;

  // preSharedKey settings value.
  string preSharedKey = 4;

  // adminURL settings value.
  string adminURL = 5;

  string interfaceName = 6;

  int64 wireguardPort = 7;

  int64 mtu = 8;

  bool disableAutoConnect = 9;

  bool serverSSHAllowed = 10;

  bool rosenpassEnabled = 11;

  bool rosenpassPermissive = 12;

  bool disable_notifications = 13;

  bool lazyConnectionEnabled = 14;

  bool blockInbound = 15;

  bool networkMonitor = 16;

  bool disable_dns = 17;

  bool disable_client_routes = 18;

  bool disable_server_routes = 19;

  bool block_lan_access = 20;

  bool enableSSHRoot = 21;

  bool enableSSHSFTP = 24;

  bool enableSSHLocalPortForwarding = 22;

  bool enableSSHRemotePortForwarding = 23;

  bool disableSSHAuth = 25;

  int32 sshJWTCacheTTL = 26;
}

// PeerState contains the latest state of a peer
message PeerState {
  string IP = 1;
  string pubKey = 2;
  string connStatus = 3;
  google.protobuf.Timestamp connStatusUpdate = 4;
  bool relayed = 5;
  string localIceCandidateType = 7;
  string remoteIceCandidateType = 8;
  string fqdn = 9;
  string localIceCandidateEndpoint = 10;
  string remoteIceCandidateEndpoint = 11;
  google.protobuf.Timestamp lastWireguardHandshake = 12;
  int64 bytesRx = 13;
  int64 bytesTx = 14;
  bool rosenpassEnabled = 15;
  repeated string networks = 16;
  google.protobuf.Duration latency = 17;
  string relayAddress = 18;
  bytes sshHostKey = 19;
}

// LocalPeerState contains the latest state of the local peer
message LocalPeerState {
  string IP = 1;
  string pubKey = 2;
  bool  kernelInterface = 3;
  string fqdn = 4;
  bool rosenpassEnabled = 5;
  bool rosenpassPermissive = 6;
  repeated string networks = 7;
}

// SignalState contains the latest state of a signal connection
message SignalState {
  string URL = 1;
  bool connected = 2;
  string error = 3;
}

// ManagementState contains the latest state of a management connection
message ManagementState {
  string URL = 1;
  bool connected = 2;
  string error = 3;
}

// RelayState contains the latest state of the relay
message RelayState {
  string URI = 1;
  bool available = 2;
  string error = 3;
}

message NSGroupState {
  repeated string servers = 1;
  repeated string domains = 2;
  bool enabled = 3;
  string error = 4;
}

// SSHSessionInfo contains information about an active SSH session
message SSHSessionInfo {
  string username = 1;
  string remoteAddress = 2;
  string command = 3;
  string jwtUsername = 4;
  repeated string portForwards = 5;
}

// SSHServerState contains the latest state of the SSH server
message SSHServerState {
  bool enabled = 1;
  repeated SSHSessionInfo sessions = 2;
}

// FullStatus contains the full state held by the Status instance
message FullStatus {
  ManagementState managementState = 1;
  SignalState     signalState = 2;
  LocalPeerState  localPeerState = 3;
  repeated PeerState peers = 4;
  repeated RelayState relays = 5;
  repeated NSGroupState dns_servers = 6;
  int32 NumberOfForwardingRules = 8;

  repeated SystemEvent events = 7;

  bool lazyConnectionEnabled = 9;
  SSHServerState sshServerState = 10;
}

// Networks
message ListNetworksRequest {
}

message ListNetworksResponse {
  repeated Network routes = 1;
}

message SelectNetworksRequest {
  repeated string networkIDs = 1;
  bool append = 2;
  bool all = 3;
}

message SelectNetworksResponse {
}

message IPList {
  repeated string ips = 1;
}

message Network {
  string ID = 1;
  string range = 2;
  bool selected = 3;
  repeated string domains = 4;
  map<string, IPList> resolvedIPs = 5;
}

// ForwardingRules
message PortInfo {
  oneof portSelection {
    uint32 port = 1;
    Range range = 2;
  }

  message Range {
    uint32 start = 1;
    uint32 end = 2;
  }
}

message ForwardingRule {
  string protocol = 1;
  PortInfo destinationPort = 2;
  string translatedAddress = 3;
  string translatedHostname = 4;
  PortInfo translatedPort = 5;
}

message ForwardingRulesResponse {
  repeated ForwardingRule rules = 1;
}


// DebugBundler
message DebugBundleRequest {
  bool anonymize = 1;
  bool systemInfo = 3;
  string uploadURL = 4;
  uint32 logFileCount = 5;
}

message DebugBundleResponse {
  string path = 1;
  string uploadedKey = 2;
  string uploadFailureReason = 3;
}

enum LogLevel {
  UNKNOWN = 0;
  PANIC = 1;
  FATAL = 2;
  ERROR = 3;
  WARN = 4;
  INFO = 5;
  DEBUG = 6;
  TRACE = 7;
}

message GetLogLevelRequest {
}

message GetLogLevelResponse {
  LogLevel level = 1;
}

message SetLogLevelRequest {
  LogLevel level = 1;
}

message SetLogLevelResponse {
}

// State represents a daemon state entry
message State {
  string name = 1;
}

// ListStatesRequest is empty as it requires no parameters
message ListStatesRequest {}

// ListStatesResponse contains a list of states
message ListStatesResponse {
  repeated State states = 1;
}

// CleanStateRequest for cleaning states
message CleanStateRequest {
  string state_name = 1;
  bool all = 2;
}

// CleanStateResponse contains the result of the clean operation
message CleanStateResponse {
  int32 cleaned_states = 1;
}

// DeleteStateRequest for deleting states
message DeleteStateRequest {
  string state_name = 1;
  bool all = 2;
}

// DeleteStateResponse contains the result of the delete operation
message DeleteStateResponse {
  int32 deleted_states = 1;
}


message SetSyncResponsePersistenceRequest {
  bool enabled = 1;
}

message SetSyncResponsePersistenceResponse {}

message TCPFlags {
  bool syn = 1;
  bool ack = 2;
  bool fin = 3;
  bool rst = 4;
  bool psh = 5;
  bool urg = 6;
}

message TracePacketRequest {
  string source_ip = 1;
  string destination_ip = 2;
  string protocol = 3;
  uint32 source_port = 4;
  uint32 destination_port = 5;
  string direction = 6;
  optional TCPFlags tcp_flags = 7;
  optional uint32 icmp_type = 8;
  optional uint32 icmp_code = 9;
}

message TraceStage {
  string name = 1;
  string message = 2;
  bool allowed = 3;
  optional string forwarding_details = 4;
}

message TracePacketResponse {
  repeated TraceStage stages = 1;
  bool final_disposition = 2;
}

message SubscribeRequest{}

message SystemEvent {
  enum Severity {
    INFO = 0;
    WARNING = 1;
    ERROR = 2;
    CRITICAL = 3;
  }

  enum Category {
    NETWORK = 0;
    DNS = 1;
    AUTHENTICATION = 2;
    CONNECTIVITY = 3;
    SYSTEM = 4;
  }

  string id = 1;
  Severity severity = 2;
  Category category = 3;
  string message = 4;
  string userMessage = 5;
  google.protobuf.Timestamp timestamp = 6;
  map<string, string> metadata = 7;
}

message GetEventsRequest {}

message GetEventsResponse {
  repeated SystemEvent events = 1;
}

message SwitchProfileRequest {
  optional string profileName = 1;
  optional string username = 2;
}

message SwitchProfileResponse {}

message SetConfigRequest {
  string username = 1;
  string profileName = 2;
  // managementUrl to authenticate.
  string managementUrl = 3;

  // adminUrl to manage keys.
  string adminURL = 4;

  optional bool rosenpassEnabled = 5;

  optional string interfaceName = 6;

  optional int64 wireguardPort = 7;

  optional string optionalPreSharedKey = 8;

  optional bool disableAutoConnect = 9;

  optional bool serverSSHAllowed = 10;

  optional bool rosenpassPermissive = 11;

  optional bool networkMonitor = 12;

  optional bool disable_client_routes = 13;
  optional bool disable_server_routes = 14;
  optional bool disable_dns = 15;
  optional bool disable_firewall = 16;
  optional bool block_lan_access = 17;

  optional bool disable_notifications = 18;

  optional bool lazyConnectionEnabled = 19;

  optional bool block_inbound = 20;

  repeated string natExternalIPs = 21;
  bool cleanNATExternalIPs = 22;

  bytes customDNSAddress = 23;

  repeated string extraIFaceBlacklist = 24;

  repeated string dns_labels = 25;
  // cleanDNSLabels clean map list of DNS labels.
  bool cleanDNSLabels = 26;

  optional google.protobuf.Duration dnsRouteInterval = 27;

  optional int64 mtu = 28;

  optional bool enableSSHRoot = 29;
  optional bool enableSSHSFTP = 30;
  optional bool enableSSHLocalPortForwarding = 31;
  optional bool enableSSHRemotePortForwarding = 32;
  optional bool disableSSHAuth = 33;
  optional int32 sshJWTCacheTTL = 34;
}

message SetConfigResponse{}

message AddProfileRequest {
  string username = 1;
  string profileName = 2;
}

message AddProfileResponse {}

message RemoveProfileRequest {
  string username = 1;
  string profileName = 2;
}

message RemoveProfileResponse {}

message ListProfilesRequest {
  string username = 1;
}

message ListProfilesResponse {
  repeated Profile profiles = 1;
}

message Profile {
  string name = 1;
  bool is_active = 2;
}

message GetActiveProfileRequest {}

message GetActiveProfileResponse {
  string profileName = 1;
  string username = 2;
}

message LogoutRequest {
  optional string profileName = 1;
  optional string username = 2;
}

message LogoutResponse {}

message GetFeaturesRequest{}

message GetFeaturesResponse{
  bool disable_profiles = 1;
  bool disable_update_settings = 2;
}

// GetPeerSSHHostKeyRequest for retrieving SSH host key for a specific peer
message GetPeerSSHHostKeyRequest {
  // peer IP address or FQDN to get SSH host key for
  string peerAddress = 1;
}

// GetPeerSSHHostKeyResponse contains the SSH host key for the requested peer
message GetPeerSSHHostKeyResponse {
  // SSH host key in SSH public key format (e.g., "ssh-ed25519 AAAAC3... hostname")
  bytes sshHostKey = 1;
  // peer IP address
  string peerIP = 2;
  // peer FQDN
  string peerFQDN = 3;
  // indicates if the SSH host key was found
  bool found = 4;
}

// RequestJWTAuthRequest for initiating JWT authentication flow
message RequestJWTAuthRequest {
  // hint for OIDC login_hint parameter (typically email address)
  optional string hint = 1;
}

// RequestJWTAuthResponse contains authentication flow information
message RequestJWTAuthResponse {
  // verification URI for user authentication
  string verificationURI = 1;
  // complete verification URI (with embedded user code)
  string verificationURIComplete = 2;
  // user code to enter on verification URI
  string userCode = 3;
  // device code for polling
  string deviceCode = 4;
  // expiration time in seconds
  int64 expiresIn = 5;
  // if a cached token is available, it will be returned here
  string cachedToken = 6;
  // maximum age of JWT tokens in seconds (from management server)
  int64 maxTokenAge = 7;
}

// WaitJWTTokenRequest for waiting for authentication completion
message WaitJWTTokenRequest {
  // device code from RequestJWTAuthResponse
  string deviceCode = 1;
  // user code for verification
  string userCode = 2;
}

// WaitJWTTokenResponse contains the JWT token after authentication
message WaitJWTTokenResponse {
  // JWT token (access token or ID token)
  string token = 1;
  // token type (e.g., "Bearer")
  string tokenType = 2;
  // expiration time in seconds
  int64 expiresIn = 3;
}

// StartCPUProfileRequest for starting CPU profiling
message StartCPUProfileRequest {}

// StartCPUProfileResponse confirms CPU profiling has started
message StartCPUProfileResponse {}

// StopCPUProfileRequest for stopping CPU profiling
message StopCPUProfileRequest {}

// StopCPUProfileResponse confirms CPU profiling has stopped
message StopCPUProfileResponse {}

message InstallerResultRequest {
}

message InstallerResultResponse {
  bool success = 1;
  string errorMsg = 2;
}
