import { Repository } from 'typeorm';
import { ClusterEntity } from '../entities/cluster.entity';
import { ClusterNodeEntity, NodeType } from '../entities/cluster-node.entity';
import { InfrastructureOperationEntity } from '../../servers/entities/infrastructure-operations.entity';
import { ApplicationEntity } from '../../../applications/entities/application.entity';
import { ProviderFactory } from '../../../providers/services/provider.factory';
import { KubernetesService } from '../../shared/services/kubernetes.service';
import { EncryptionService } from '../../../shared/encryption/services/encryption.service';
import { BillingIntervalsService } from './billing-intervals.service';
export interface ScaleNodeImpactDto {
    clusterId: string;
    node: {
        id: string;
        name: string;
        nodeType: NodeType;
        providerResourceId: string;
        currentServerType: string;
        isLocked: boolean;
    };
    affectedDedicatedApps: Array<{
        id: string;
        slug: string;
    }>;
    expectedDowntimeMs: number;
    warning: string;
}
export interface ScaleNodeRequest {
    targetServerType: string;
    upgradeDisk?: boolean;
}
export interface ExpandSharedVolumeRequest {
    targetSizeGb: number;
}
export declare class ClusterNodeScalingService {
    private readonly clusterRepository;
    private readonly nodeRepository;
    private readonly operationRepository;
    private readonly applicationRepository;
    private readonly providerFactory;
    private readonly kubernetesService;
    private readonly encryptionService;
    private readonly billingIntervals;
    private readonly logger;
    constructor(clusterRepository: Repository<ClusterEntity>, nodeRepository: Repository<ClusterNodeEntity>, operationRepository: Repository<InfrastructureOperationEntity>, applicationRepository: Repository<ApplicationEntity>, providerFactory: ProviderFactory, kubernetesService: KubernetesService, encryptionService: EncryptionService, billingIntervals: BillingIntervalsService);
    previewScaleNode(clusterId: string, nodeId: string): Promise<ScaleNodeImpactDto>;
    scaleNode(clusterId: string, nodeId: string, request: ScaleNodeRequest, userId?: string): Promise<InfrastructureOperationEntity>;
    expandSharedVolume(clusterId: string, request: ExpandSharedVolumeRequest, userId?: string): Promise<InfrastructureOperationEntity>;
    uncordonNode(clusterId: string, nodeId: string): Promise<void>;
    assertNodeUnlocked(clusterId: string, nodeId: string): Promise<void>;
    private resolveClusterAndNode;
    private findDedicatedAppsOnNode;
    private advanceStep;
    /**
     * Poll a TCP connect on `host:port` until it succeeds or the timeout
     * expires. Used as a tunnel-free liveness check for the master node
     * (Traefik on :80 answers once k3s + ingress are up).
     */
    private waitForTcpOpen;
    private waitForServerStatus;
    /**
     * Cross-provider status reconciliation. Hetzner returns `off`/`running`,
     * Scaleway returns `stopped`/`running`, Contabo and others have their own
     * vocabulary. Normalise to the two canonical states we care about during
     * a scale operation.
     */
    private matchesExpectedStatus;
    private formatVolumeRefForProvider;
    /**
     * Scaleway SBS volumes are zone-scoped (e.g. `fr-par-1`), but the cluster
     * only records the parent region (`fr-par`). Resolve the zone by looking
     * at the master node's providerResourceId, which encodes it as
     * `instance:<zone>:<uuid>`. For Hetzner this is a no-op — the volume id is
     * a numeric global id that doesn't need a zone prefix.
     */
    private resolveVolumeZone;
    private resolveBlockDevice;
    private runResizeFsJob;
}
