// File: api/v1alpha1/kat.proto
syntax = "proto3";

package v1alpha1;

option go_package = "git.dws.rip/dubey/kat"; // Adjust to your actual go module path

import "google/protobuf/timestamp.proto";

// Common Metadata (RFC 3.2, Phase 0 Docs)
message ObjectMeta {
  string name = 1;
  string namespace = 2;
  string uid = 3;
  int64 generation = 4;
  string resource_version = 5; // e.g., etcd ModRevision
  google.protobuf.Timestamp creation_timestamp = 6;
  map<string, string> labels = 7;
  map<string, string> annotations = 8;
}

// Workload (RFC 3.2)
enum WorkloadType {
  WORKLOAD_TYPE_UNSPECIFIED = 0;
  SERVICE = 1;
  JOB = 2;
  DAEMON_SERVICE = 3;
}

message GitSource {
  string repository = 1;
  string branch = 2;
  string tag = 3;
  string commit = 4;
}

message WorkloadSource {
  oneof source_type {
    string image = 1; // Direct image reference
    GitSource git = 2;   // Build from Git
  }
  string cache_image = 3; // Optional: Registry path for build cache layers (used with git source)
}

enum UpdateStrategyType {
  UPDATE_STRATEGY_TYPE_UNSPECIFIED = 0;
  ROLLING = 1;
  SIMULTANEOUS = 2;
}

message RollingUpdateStrategy {
  string max_surge = 1; // Can be int or percentage string e.g., "1" or "10%"
}

message UpdateStrategy {
  UpdateStrategyType type = 1;
  RollingUpdateStrategy rolling = 2; // Relevant if type is ROLLING
}

enum RestartCondition {
  RESTART_CONDITION_UNSPECIFIED = 0;
  NEVER = 1;
  MAX_COUNT = 2;
  ALWAYS = 3;
}

message RestartPolicy {
  RestartCondition condition = 1;
  int32 max_restarts = 2;    // Used if condition=MAX_COUNT
  int32 reset_seconds = 3; // Used if condition=MAX_COUNT
}

message Toleration {
  string key = 1;
  enum Operator {
    OPERATOR_UNSPECIFIED = 0;
    EXISTS = 1;
    EQUAL = 2;
  }
  Operator operator = 2;
  string value = 3; // Needed if operator=EQUAL
  enum Effect {
    EFFECT_UNSPECIFIED = 0;
    NO_SCHEDULE = 1;
    PREFER_NO_SCHEDULE = 2;
    // NO_EXECUTE (not in RFC v1 scope for tolerations, but common)
  }
  Effect effect = 4;
}

message EnvVar {
  string name = 1;
  string value = 2;
}

message VolumeMount {
  string name = 1;       // Volume name from spec.volumes
  string mount_path = 2; // Path inside container
  string sub_path = 3;   // Optional: Mount sub-directory
  bool read_only = 4;    // Optional: Default false
}

message ResourceRequests {
  string cpu = 1;    // e.g., "100m"
  string memory = 2; // e.g., "64Mi"
}

message ResourceLimits {
  string cpu = 1;    // e.g., "1"
  string memory = 2; // e.g., "256Mi"
}

enum GPUDriver {
  GPU_DRIVER_UNSPECIFIED = 0;
  ANY = 1;
  NVIDIA = 2;
  AMD = 3;
}

message GPUSpec {
  GPUDriver driver = 1;
  int32 min_vram_mb = 2; // Minimum GPU memory required
}

message ContainerResources {
  ResourceRequests requests = 1;
  ResourceLimits limits = 2;
  GPUSpec gpu = 3;
}

message Container {
  string name = 1; // Optional: Informational name
  repeated string command = 2;
  repeated string args = 3;
  repeated EnvVar env = 4;
  repeated VolumeMount volume_mounts = 5;
  ContainerResources resources = 6;
}

message SimpleClusterStorageVolumeSource {
  // Empty, implies agent creates dir under volumeBasePath
}

enum HostPathType {
  HOST_PATH_TYPE_UNSPECIFIED = 0; // No check, mount whatever is there or fail
  DIRECTORY_OR_CREATE = 1;
  DIRECTORY = 2;
  FILE_OR_CREATE = 3;
  FILE = 4;
  SOCKET = 5;
}

message HostMountVolumeSource {
  string host_path = 1;       // Absolute path on host
  HostPathType ensure_type = 2; // Optional: Type to ensure/check
}

message Volume {
  string name = 1; // Name referenced by volumeMounts
  oneof volume_source {
    SimpleClusterStorageVolumeSource simple_cluster_storage = 2;
    HostMountVolumeSource host_mount = 3;
  }
}

message WorkloadSpec {
  WorkloadType type = 1;
  WorkloadSource source = 2;
  int32 replicas = 3; // Required for SERVICE
  UpdateStrategy update_strategy = 4;
  RestartPolicy restart_policy = 5;
  map<string, string> node_selector = 6;
  repeated Toleration tolerations = 7;
  Container container = 8;
  repeated Volume volumes = 9;
}

message WorkloadStatus {
  // Placeholder for Phase 0. Will be expanded later.
  // Example fields:
  // int32 observed_generation = 1;
  // int32 ready_replicas = 2;
  // string condition = 3; // e.g., "Available", "Progressing", "Failed"
}

message Workload {
  ObjectMeta metadata = 1;
  WorkloadSpec spec = 2;
  WorkloadStatus status = 3;
}

// VirtualLoadBalancer (RFC 3.3)
message PortSpec {
  string name = 1;          // Optional: e.g., "web", "grpc"
  int32 container_port = 2; // Port app listens on in container
  string protocol = 3;      // Optional: TCP | UDP. Default TCP.
}

message ExecHealthCheck {
  repeated string command = 1; // Exit 0 = healthy
}

message HealthCheck {
  ExecHealthCheck exec = 1;
  int32 initial_delay_seconds = 2;
  int32 period_seconds = 3;
  int32 timeout_seconds = 4;
  int32 success_threshold = 5;
  int32 failure_threshold = 6;
}

message IngressRule {
  string host = 1;
  string path = 2;
  string service_port_name = 3; // Name of port from PortSpec
  int32 service_port = 4;       // Port number from PortSpec (overrides name)
  bool tls = 5;                 // Signal for ACME
}

message VirtualLoadBalancerSpec {
  repeated PortSpec ports = 1;
  HealthCheck health_check = 2;
  repeated IngressRule ingress = 3;
}

message VirtualLoadBalancer {
  ObjectMeta metadata = 1; // Name likely matches Workload name
  VirtualLoadBalancerSpec spec = 2;
  // VirtualLoadBalancerStatus status = 3; // Placeholder
}

// JobDefinition (RFC 3.4)
message JobDefinitionSpec {
  string schedule = 1;             // Optional: Cron schedule
  int32 completions = 2;           // Optional: Default 1
  int32 parallelism = 3;           // Optional: Default 1
  int32 active_deadline_seconds = 4; // Optional
  int32 backoff_limit = 5;         // Optional: Default 3
}

message JobDefinition {
  ObjectMeta metadata = 1; // Name likely matches Workload name
  JobDefinitionSpec spec = 2;
  // JobDefinitionStatus status = 3; // Placeholder
}

// BuildDefinition (RFC 3.5)
message BuildCache {
    string registry_path = 1; // e.g., "myreg.com/cache/myapp"
}

message BuildDefinitionSpec {
  string build_context = 1;    // Optional: Path relative to repo root. Defaults to "."
  string dockerfile_path = 2;  // Optional: Path relative to buildContext. Defaults to "./Dockerfile"
  map<string, string> build_args = 3; // Optional
  string target_stage = 4;     // Optional
  string platform = 5;         // Optional: e.g., "linux/arm64"
  BuildCache cache = 6;        // Optional
}

message BuildDefinition {
  ObjectMeta metadata = 1; // Name likely matches Workload name
  BuildDefinitionSpec spec = 2;
  // BuildDefinitionStatus status = 3; // Placeholder
}

// Namespace (RFC 3.7)
message NamespaceSpec {
  // Potentially finalizers or other future spec fields
}

message NamespaceStatus {
  // string phase = 1; // e.g., "Active", "Terminating"
}

message Namespace {
  ObjectMeta metadata = 1;
  NamespaceSpec spec = 2;
  NamespaceStatus status = 3;
}

// Node (Internal Representation - RFC 3.8)
message NodeResources {
  string cpu = 1;    // e.g., "2000m"
  string memory = 2; // e.g., "4096Mi"
  map<string, string> custom_resources = 3; // e.g., for GPUs "nvidia.com/gpu: 2"
}

message NodeStatusDetails {
  NodeResources capacity = 1;
  NodeResources allocatable = 2;
  // repeated WorkloadInstanceStatus workload_instances = 3; // Define later
  // OverlayNetworkStatus overlay_network = 4; // Define later
  string condition = 5; // e.g., "Ready", "NotReady", "Draining"
  google.protobuf.Timestamp last_heartbeat_time = 6;
}

message Taint { // From RFC 1.5, used in NodeSpec
  string key = 1;
  string value = 2;
  enum Effect {
    EFFECT_UNSPECIFIED = 0;
    NO_SCHEDULE = 1;
    PREFER_NO_SCHEDULE = 2;
    // NO_EXECUTE (not in RFC v1 scope for taints, but common)
  }
  Effect effect = 3;
}

message NodeSpec {
  repeated Taint taints = 1;
  string overlay_subnet = 2; // Assigned by leader
  // string provider_id = 3; // Cloud provider specific ID
  // map<string, string> labels = 4; // Node labels, distinct from metadata.labels
  // map<string, string> annotations = 5; // Node annotations
}

message Node {
  ObjectMeta metadata = 1; // Name is the unique node name/ID
  NodeSpec spec = 2;
  NodeStatusDetails status = 3;
}

// ClusterConfiguration (RFC 3.9)
message ClusterConfigurationSpec {
  string cluster_cidr = 1;
  string service_cidr = 2;
  int32 node_subnet_bits = 3;
  string cluster_domain = 4;
  int32 agent_port = 5;
  int32 api_port = 6;
  int32 etcd_peer_port = 7;
  int32 etcd_client_port = 8;
  string volume_base_path = 9;
  string backup_path = 10;
  int32 backup_interval_minutes = 11;
  int32 agent_tick_seconds = 12;
  int32 node_loss_timeout_seconds = 13;
}

message ClusterConfiguration {
  ObjectMeta metadata = 1; // e.g., name of the cluster
  ClusterConfigurationSpec spec = 2;
  // ClusterConfigurationStatus status = 3; // Placeholder
}