import { SQLiteCloudProviderTokensRepository } from '../../repositories/sqlite-cloud-provider-tokens.repository.js';
import { LocalSecretBox } from '../../services/crypto/local-secret-box.js';
import { loadOrCreateSecretKey } from '../../services/crypto/secret-key-file.js';
import { getShepHomeDir } from '../../services/filesystem/shep-directory.service.js';
import { CloudDeploymentProviderRegistry, CLOUD_DEPLOYMENT_PROVIDER_TOKEN, } from '../../services/cloud-deploy/cloud-deployment-provider.registry.js';
import { CloudflarePagesProvider } from '../../services/cloud-deploy/cloudflare-pages.provider.js';
import { VercelProviderStub } from '../../services/cloud-deploy/vercel.provider.stub.js';
import { NetlifyProviderStub } from '../../services/cloud-deploy/netlify.provider.stub.js';
import { AwsAmplifyProviderStub } from '../../services/cloud-deploy/aws-amplify.provider.stub.js';
import { GcpCloudRunProviderStub } from '../../services/cloud-deploy/gcp-cloud-run.provider.stub.js';
import { InMemoryCloudDeploymentEventBus } from '../../services/events/in-memory-cloud-deployment-event-bus.js';
import { GitRemoteService } from '../../services/git/git-remote.service.js';
import { CloudDeploymentProvider } from '../../../domain/generated/output.js';
import { ListCloudProvidersUseCase } from '../../../application/use-cases/cloud-deploy/list-cloud-providers.use-case.js';
import { ConnectCloudProviderUseCase } from '../../../application/use-cases/cloud-deploy/connect-cloud-provider.use-case.js';
import { SelectCloudProviderUseCase } from '../../../application/use-cases/cloud-deploy/select-cloud-provider.use-case.js';
import { InitiateCloudDeploymentUseCase } from '../../../application/use-cases/cloud-deploy/initiate-cloud-deployment.use-case.js';
import { GetCloudDeploymentStatusUseCase } from '../../../application/use-cases/cloud-deploy/get-cloud-deployment-status.use-case.js';
import { CreateGitRemoteUseCase } from '../../../application/use-cases/cloud-deploy/create-git-remote.use-case.js';
import { EnsureGhAuthenticatedUseCase } from '../../../application/use-cases/cloud-deploy/ensure-gh-authenticated.use-case.js';
import { GetGitStatusUseCase } from '../../../application/use-cases/cloud-deploy/get-git-status.use-case.js';
import { SyncRepoUseCase } from '../../../application/use-cases/cloud-deploy/sync-repo.use-case.js';
/**
 * Cloud deployment registrations (spec 089).
 *
 * Registers the secret box, per-provider adapters, provider registry, event bus,
 * git-remote service, token repository, and the cloud-deploy use cases.
 */
export function registerCloudDeploy(container) {
    // FetchFunction — injected into CloudflarePagesProvider so tests can swap it.
    container.registerInstance('FetchFunction', globalThis.fetch.bind(globalThis));
    // Clock for the cloudflare provider's polling loop. Tests can override.
    // Tsyringe does not honor TypeScript default-parameter values for @inject,
    // so a real registration is required even though the constructor has a default.
    container.registerInstance('CloudflareProviderClock', {
        now: () => Date.now(),
        sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
    });
    // LocalSecretBox keyed by ~/.shep/secret.key (atomic wx create on first run).
    container.register(LocalSecretBox, {
        useFactory: () => new LocalSecretBox(loadOrCreateSecretKey(getShepHomeDir())),
    });
    // Token repository — encrypts with the shared LocalSecretBox.
    container.register('ICloudProviderTokensRepository', {
        useFactory: (c) => {
            const db = c.resolve('Database');
            const box = c.resolve(LocalSecretBox);
            return new SQLiteCloudProviderTokensRepository(db, box);
        },
    });
    // Per-provider registrations (mirrors AgentSessionRepositoryRegistry pattern).
    container.registerSingleton(CLOUD_DEPLOYMENT_PROVIDER_TOKEN(CloudDeploymentProvider.CloudflarePages), CloudflarePagesProvider);
    container.registerSingleton(CLOUD_DEPLOYMENT_PROVIDER_TOKEN(CloudDeploymentProvider.Vercel), VercelProviderStub);
    container.registerSingleton(CLOUD_DEPLOYMENT_PROVIDER_TOKEN(CloudDeploymentProvider.Netlify), NetlifyProviderStub);
    container.registerSingleton(CLOUD_DEPLOYMENT_PROVIDER_TOKEN(CloudDeploymentProvider.AwsAmplify), AwsAmplifyProviderStub);
    container.registerSingleton(CLOUD_DEPLOYMENT_PROVIDER_TOKEN(CloudDeploymentProvider.GcpCloudRun), GcpCloudRunProviderStub);
    container.registerSingleton('ICloudDeploymentProviderRegistry', CloudDeploymentProviderRegistry);
    container.registerSingleton('ICloudDeploymentEventBus', InMemoryCloudDeploymentEventBus);
    container.registerSingleton('IGitRemoteService', GitRemoteService);
    // Cloud deployment use cases (spec 089). String-token aliases added so
    // web routes can do `resolve<T>('UseCaseName')` — needed because next.js
    // server-side resolve lives outside the core di bootstrap.
    container.registerSingleton(ListCloudProvidersUseCase);
    container.register('ListCloudProvidersUseCase', {
        useFactory: (c) => c.resolve(ListCloudProvidersUseCase),
    });
    container.registerSingleton(ConnectCloudProviderUseCase);
    container.register('ConnectCloudProviderUseCase', {
        useFactory: (c) => c.resolve(ConnectCloudProviderUseCase),
    });
    container.registerSingleton(SelectCloudProviderUseCase);
    container.register('SelectCloudProviderUseCase', {
        useFactory: (c) => c.resolve(SelectCloudProviderUseCase),
    });
    container.registerSingleton(InitiateCloudDeploymentUseCase);
    container.register('InitiateCloudDeploymentUseCase', {
        useFactory: (c) => c.resolve(InitiateCloudDeploymentUseCase),
    });
    container.registerSingleton(GetCloudDeploymentStatusUseCase);
    container.register('GetCloudDeploymentStatusUseCase', {
        useFactory: (c) => c.resolve(GetCloudDeploymentStatusUseCase),
    });
    container.registerSingleton(CreateGitRemoteUseCase);
    container.register('CreateGitRemoteUseCase', {
        useFactory: (c) => c.resolve(CreateGitRemoteUseCase),
    });
    container.registerSingleton(EnsureGhAuthenticatedUseCase);
    container.register('EnsureGhAuthenticatedUseCase', {
        useFactory: (c) => c.resolve(EnsureGhAuthenticatedUseCase),
    });
    container.registerSingleton(GetGitStatusUseCase);
    container.register('GetGitStatusUseCase', {
        useFactory: (c) => c.resolve(GetGitStatusUseCase),
    });
    container.registerSingleton(SyncRepoUseCase);
    container.register('SyncRepoUseCase', {
        useFactory: (c) => c.resolve(SyncRepoUseCase),
    });
}
