/**
 * Provider-side volume operations: snapshot creation, listing, deletion, and
 * restore-to-new-PVC. Abstracts over the asymmetry between providers that
 * support native CSI VolumeSnapshot (Scaleway, OVH, IONOS) and those that
 * don't (Hetzner — see csi-driver issue #88, no snapshot/clone support).
 *
 * The user-facing terminology is uniform ("snapshot"), but on providers
 * without native support the implementation may degrade to a labeled PVC
 * clone via the copy-pod pattern (a Job that mounts source + dest PVC and
 * tars data across).
 *
 * The capabilities object lets higher-level services (CLI, cost estimator,
 * migration orchestrator) decide which operations to expose and how much
 * they will cost.
 */
export interface VolumeOperationsCapabilities {
    /**
     * True when the storage backend supports cheap retention of snapshots as a
     * separate object (e.g. Scaleway Block Storage Snapshots at ~€0.032/GB-mo).
     * False on providers where a "snapshot" is a full PVC clone billed at the
     * full volume rate (e.g. Hetzner). When false, snapshot CLI commands
     * should warn the user about the per-snapshot cost and the orchestrator
     * should prefer one-shot migration over keeping snapshots around.
     */
    supportsSnapshotRetention: boolean;
    /**
     * True when the CSI driver implements the standard
     * `snapshot.storage.k8s.io/v1` VolumeSnapshot API. False on Hetzner.
     * Drives the migration strategy selection: CSI snapshot vs copy-pod.
     */
    supportsCsiSnapshot: boolean;
    /**
     * True when the only viable migration strategy is the universal copy-pod
     * fallback (a Job that copies bytes between PVCs). Mutually exclusive
     * with supportsCsiSnapshot in the current design.
     */
    requiresCopyPodFallback: boolean;
    /**
     * Approximate price for retaining a snapshot, in EUR per GB per month.
     * Null when retention is not supported (snapshot price equals volume
     * price in that case — surfaced separately by the cost estimator).
     */
    snapshotCostPerGbMonthEur: number | null;
}
export interface CreateSnapshotInput {
    /** Kubeconfig of the workload cluster where the source PVC lives. */
    kubeconfig: string;
    /** Namespace of the source PVC. */
    namespace: string;
    /** Source PVC name (the live volume to be snapshotted). */
    sourcePvcName: string;
    /** Desired snapshot resource name (cluster-unique within namespace). */
    snapshotName: string;
    /**
     * Labels applied to the snapshot resource. Always populated by Flui with
     * `flui.cloud/managed-by=flui-cloud`, `flui-app-id=<id>`,
     * `flui.cloud/created-by=<job-id>` so the reaper can identify orphans.
     */
    labels: Record<string, string>;
}
export interface SnapshotResult {
    /**
     * Unique identifier of the created snapshot resource. On providers with
     * CSI snapshot this is the VolumeSnapshot name; on copy-pod fallback it
     * is the cloned PVC name.
     */
    snapshotId: string;
    /** Provider implementation discriminant: 'csi-snapshot' | 'pvc-clone'. */
    kind: SnapshotKind;
    /** Namespace where the snapshot resource lives. */
    namespace: string;
    /** Size of the source PVC in GB at snapshot time. Used for cost reporting. */
    sourceSizeGb: number;
    /** Snapshot creation timestamp (ISO 8601). */
    createdAt: string;
    /** Provider-side ready state — true once the snapshot can be used to provision a new PVC. */
    ready: boolean;
}
export type SnapshotKind = 'csi-snapshot' | 'pvc-clone';
export interface ListSnapshotsInput {
    kubeconfig: string;
    /** Optional namespace filter. When omitted, lists across all namespaces. */
    namespace?: string;
    /**
     * Optional label selector to narrow the list (e.g. `flui-app-id=<id>` for
     * per-app listing).
     */
    labelSelector?: string;
}
export interface SnapshotSummary {
    snapshotId: string;
    kind: SnapshotKind;
    namespace: string;
    /** Source PVC name, when known from labels or annotations. */
    sourcePvcName?: string;
    /** flui-app-id label value, when present. */
    appId?: string;
    /** Size of the snapshot data in GB (best-effort; for csi-snapshot this is the restoreSize). */
    sizeGb?: number;
    /** Snapshot creation timestamp (ISO 8601). */
    createdAt: string;
    /** Whether the snapshot is currently usable to provision a new PVC. */
    ready: boolean;
    /** All labels on the snapshot resource. */
    labels: Record<string, string>;
}
export interface CreatePvcFromSnapshotInput {
    kubeconfig: string;
    namespace: string;
    /** Source snapshot to restore from. */
    snapshotId: string;
    /** Desired name of the new PVC. */
    newPvcName: string;
    /** Storage class for the new PVC. */
    storageClassName: string;
    /** Storage size for the new PVC (must be >= source snapshot size). */
    sizeGb: number;
    /**
     * Optional node hint. The orchestrator typically wants the new PVC to
     * bind to a specific node (the migration target). The implementation may
     * use this hint via WaitForFirstConsumer + a same-node placeholder pod.
     */
    preferredNode?: string;
    /**
     * Labels applied to the new PVC. Same convention as snapshot labels.
     */
    labels: Record<string, string>;
}
export interface DeleteSnapshotInput {
    kubeconfig: string;
    namespace: string;
    snapshotId: string;
    /** When true, ignore "not found" and return success. */
    ignoreNotFound?: boolean;
}
/**
 * Provider-side volume operations contract. Each cloud provider that hosts
 * Flui workload clusters provides an implementation. The orchestrator
 * consumes this interface only — it does not branch on provider type.
 */
export interface IVolumeOperations {
    readonly capabilities: VolumeOperationsCapabilities;
    createSnapshot(input: CreateSnapshotInput): Promise<SnapshotResult>;
    deleteSnapshot(input: DeleteSnapshotInput): Promise<void>;
    listSnapshots(input: ListSnapshotsInput): Promise<SnapshotSummary[]>;
    createPvcFromSnapshot(input: CreatePvcFromSnapshotInput): Promise<{
        pvcName: string;
    }>;
}
