syntax = "proto3";

package towerops.agent;

// Configuration received from the API
message AgentConfig {
  string version = 1;
  uint32 poll_interval_seconds = 2;
  repeated Device devices = 3;
}

message Device {
  string id = 1;
  string name = 2;
  string ip_address = 3;
  SnmpConfig snmp = 4;
  uint32 poll_interval_seconds = 5;
  repeated Sensor sensors = 6;
  repeated Interface interfaces = 7;
  bool monitoring_enabled = 8;
  uint32 check_interval_seconds = 9;
}

message SnmpConfig {
  bool enabled = 1;
  string version = 2;
  string community = 3;
  uint32 port = 4;
}

message Sensor {
  string id = 1;
  string type = 2;
  string oid = 3;
  double divisor = 4;
  string unit = 5;
  map<string, string> metadata = 6;
}

message Interface {
  string id = 1;
  uint32 if_index = 2;
  string if_name = 3;
}

// Metrics submitted to the API
message MetricBatch {
  repeated Metric metrics = 1;
}

message Metric {
  oneof metric_type {
    SensorReading sensor_reading = 1;
    InterfaceStat interface_stat = 2;
    NeighborDiscovery neighbor_discovery = 3;
    MonitoringCheck monitoring_check = 4;
  }
}

message SensorReading {
  string sensor_id = 1;
  double value = 2;
  string status = 3;
  int64 timestamp = 4; // Unix timestamp in seconds
}

message InterfaceStat {
  string interface_id = 1;
  int64 if_in_octets = 2;
  int64 if_out_octets = 3;
  int64 if_in_errors = 4;
  int64 if_out_errors = 5;
  int64 if_in_discards = 6;
  int64 if_out_discards = 7;
  int64 timestamp = 8; // Unix timestamp in seconds
}

message NeighborDiscovery {
  string interface_id = 1;
  string protocol = 2; // "lldp" or "cdp"
  string remote_chassis_id = 3;
  string remote_system_name = 4;
  string remote_system_description = 5;
  string remote_platform = 6;
  string remote_port_id = 7;
  string remote_port_description = 8;
  string remote_address = 9;
  repeated string remote_capabilities = 10;
  int64 timestamp = 11; // Unix timestamp in seconds
}

message MonitoringCheck {
  string device_id = 1;
  string status = 2; // "success" or "failure"
  double response_time_ms = 3; // Optional - only present on success
  int64 timestamp = 4; // Unix timestamp in seconds
}

// Heartbeat metadata
message HeartbeatMetadata {
  string version = 1;
  string hostname = 2;
  uint64 uptime_seconds = 3;
}

message HeartbeatResponse {
  string status = 1;
}

// WebSocket-specific messages

enum JobType {
  DISCOVER = 0;
  POLL = 1;
  MIKROTIK = 2;
  TEST_CREDENTIALS = 3;
  PING = 4;
}

enum QueryType {
  GET = 0;
  WALK = 1;
}

message AgentJobList {
  repeated AgentJob jobs = 1;
}

message AgentJob {
  string job_id = 1;
  JobType job_type = 2;
  string device_id = 3;
  SnmpDevice snmp_device = 4;
  repeated SnmpQuery queries = 5;
  MikrotikDevice mikrotik_device = 6;
  repeated MikrotikCommand mikrotik_commands = 7;
}

message SnmpDevice {
  string ip = 1;
  string community = 2;           // v1/v2c only (deprecated for v3)
  string version = 3;
  uint32 port = 4;

  // SNMPv3 credentials (optional, backward compatible)
  string v3_security_level = 5;  // "noAuthNoPriv" | "authNoPriv" | "authPriv"
  string v3_username = 6;
  string v3_auth_protocol = 7;   // "MD5" | "SHA" | "SHA-256" | etc.
  string v3_auth_password = 8;   // Decrypted before sending
  string v3_priv_protocol = 9;   // "DES" | "AES" | "AES-256" | etc.
  string v3_priv_password = 10;  // Decrypted before sending
}

message SnmpQuery {
  QueryType query_type = 1;
  repeated string oids = 2;
}

message SnmpResult {
  string device_id = 1;
  JobType job_type = 2;
  map<string, string> oid_values = 3;
  int64 timestamp = 4;
  string job_id = 5;
}

message AgentHeartbeat {
  string version = 1;
  string hostname = 2;
  uint64 uptime_seconds = 3;
  string ip_address = 4;
}

message AgentError {
  string device_id = 1;
  string job_id = 2;
  string message = 3;
  int64 timestamp = 4;
}

message CredentialTestResult {
  string test_id = 1;
  bool success = 2;
  string error_message = 3;  // Empty if success
  string system_description = 4;  // sysDescr.0 value if success
  int64 timestamp = 5;
}

// MikroTik RouterOS API messages

message MikrotikDevice {
  string ip = 1;
  uint32 port = 2;
  string username = 3;
  string password = 4;
  bool use_ssl = 5;
  uint32 ssh_port = 6;
}

message MikrotikCommand {
  string command = 1;
  map<string, string> args = 2;
}

message MikrotikResult {
  string device_id = 1;
  string job_id = 2;
  repeated MikrotikSentence sentences = 3;
  string error = 4;
  int64 timestamp = 5;
}

message MikrotikSentence {
  map<string, string> attributes = 1;
}
