/**
 * ServiceRegistryTypes — shared V1 contract for live substrate directory entries.
 *
 * `system.registry` owns live, bus-addressable service/app/feed/actor/runtime
 * entries inside one namespace. Durable package metadata, Device enrollment,
 * identity, credentials, and Host supervision have separate owners.
 */

import type { RuntimeInventoryPlacementMetadata } from './placement.js';

export type ServiceRegistryEntryKindV1 =
  | 'actor'
  | 'service'
  | 'app'
  | 'feed'
  | 'runtime'
  | 'gateway'
  | 'connector'
  | 'resource';

export type MountClaimModeV1 =
  | 'authoritative'
  | 'proxy'
  | 'mirror'
  | 'local-only'
  | 'pool-member';

export type MountClaimResultV1 =
  | 'accepted'
  | 'rejected'
  | 'collision'
  | 'joined-pool'
  | 'standby'
  | 'leader'
  | 'mirror'
  | 'local-only';

export type ServiceRegistryLoadBalancingModeV1 =
  | 'none'
  | 'round-robin'
  | 'least-loaded'
  | 'broadcast';

export type HealthStatusV1 =
  | 'ok'
  | 'degraded'
  | 'error'
  | 'unknown'
  | 'starting'
  | 'stopped';

export type AppSurfaceTypeV1 = 'page' | 'panel' | 'modal' | 'widget';

export type RegistryWatchEventTypeV1 = 'upsert' | 'release' | 'renew' | 'expired';

export interface CapabilityDeclarationV1 {
  id: string;
  name?: string;
  description?: string;
  inputSchema?: Record<string, unknown>;
  outputSchema?: Record<string, unknown>;
}

export interface IntentDeclarationV1 {
  intent: string;
  description?: string;
  inputSchema?: Record<string, unknown>;
  outputSchema?: Record<string, unknown>;
}

export interface ServiceInstanceV1 {
  accepts: string[];
  emits: string[];
  streams: string[];
  capabilities: CapabilityDeclarationV1[];
  intents: IntentDeclarationV1[];
}

export interface AppSurfaceV1 {
  route: string;
  title: string;
  icon?: string;
  surface: AppSurfaceTypeV1;
  openable: boolean;
  appName?: string;
}

export interface ServiceRegistryPlacementV1 {
  deviceId?: string;
  hostId?: string;
  runtimeId?: string;
  packageId?: string;
  actorId?: string;
  deploymentInstanceId?: string;
  instanceName?: string;
  packageRef?: string;
  cardinality?: RuntimeInventoryPlacementMetadata['cardinality'];
  claimMode?: RuntimeInventoryPlacementMetadata['claimMode'];
  logicalMount?: string;
  physicalMount?: string;
  callable?: boolean;
  standbyReason?: string;
  placementEpoch?: number;
}

export interface MountClaimV1 {
  mode: MountClaimModeV1;
  result: MountClaimResultV1;
  ownerComponentId: string;
  electionGroup?: string;
  leaderId?: string;
  loadBalancing: ServiceRegistryLoadBalancingModeV1;
  claimedAt: number;
  renewedAt: number;
  expiresAt: number;
}

export interface HealthSnapshotV1 {
  status: HealthStatusV1;
  reason?: string;
  updatedAt: number;
}

export interface ServiceRegistryEntryV1 {
  version: '1';
  namespaceRoot: string;
  mount: string;
  kind: ServiceRegistryEntryKindV1;
  service?: ServiceInstanceV1;
  app?: AppSurfaceV1;
  placement: ServiceRegistryPlacementV1;
  claim: MountClaimV1;
  health: HealthSnapshotV1;
  ttlMs: number;
  metadata?: Record<string, unknown>;
}

export interface RegistryWatchEventV1 {
  version: '1';
  sequence: number;
  type: RegistryWatchEventTypeV1;
  namespaceRoot: string;
  mount: string;
  at: number;
  entry?: ServiceRegistryEntryV1;
}
