/**
 * Start Application Deployment Use Case
 *
 * Starts a local dev server for an application, keyed by the application's
 * stable ID (UUID) so multiple applications at similar paths can't collide
 * in the `dev_servers` table.
 *
 * Business Rules:
 * - applicationId must be non-empty
 * - The application must exist in the repository
 * - The application's repositoryPath must exist on disk
 * - Rejects the currently running Shep instance's own repository
 *
 * The `IDeploymentService` writes to the `dev_servers` SQLite table on spawn,
 * updates it on Ready (with the detected URL), and removes the row on stop —
 * so deployment state is fully persisted across page reloads AND service
 * restarts (`recoverAll()` reconciles live PIDs on startup).
 *
 * Extracted from the `deployApplication` server action as part of clean-arch
 * violations #1, #2, #3 cleanup (see specs/089-one-click-cloud-deploy/
 * clean-arch-violations.md).
 */
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { inject, injectable } from 'tsyringe';
import { DeploymentState } from '../../../domain/generated/output.js';
import { ApplicationNotFoundError } from '../../../domain/errors/application-not-found.error.js';
import { ApplicationRepositoryNotOnDiskError } from '../../../domain/errors/application-repository-not-on-disk.error.js';
import { CannotDeploySelfError } from '../../../domain/errors/cannot-deploy-self.error.js';
let StartApplicationDeploymentUseCase = class StartApplicationDeploymentUseCase {
    applicationRepo;
    fileSystem;
    shepInstance;
    deploymentService;
    logger;
    constructor(applicationRepo, fileSystem, shepInstance, deploymentService, logger) {
        this.applicationRepo = applicationRepo;
        this.fileSystem = fileSystem;
        this.shepInstance = shepInstance;
        this.deploymentService = deploymentService;
        this.logger = logger;
    }
    async execute(input) {
        const { applicationId } = input;
        this.logger.info('[StartApplicationDeploymentUseCase] called', { applicationId });
        if (!applicationId?.trim()) {
            this.logger.warn('[StartApplicationDeploymentUseCase] rejected — applicationId is empty');
            throw new Error('applicationId is required');
        }
        const application = await this.applicationRepo.findById(applicationId);
        if (!application) {
            this.logger.warn('[StartApplicationDeploymentUseCase] application not found', {
                applicationId,
            });
            throw new ApplicationNotFoundError(applicationId);
        }
        const repositoryPath = application.repositoryPath;
        this.logger.info('[StartApplicationDeploymentUseCase] application found', {
            applicationId,
            repositoryPath,
        });
        if (!this.fileSystem.pathExists(repositoryPath)) {
            this.logger.warn('[StartApplicationDeploymentUseCase] repository path does not exist on disk', { applicationId, repositoryPath });
            throw new ApplicationRepositoryNotOnDiskError(applicationId, repositoryPath);
        }
        if (this.shepInstance.isSameInstance(repositoryPath)) {
            this.logger.warn('[StartApplicationDeploymentUseCase] rejected — target is the running shep instance', { applicationId, repositoryPath });
            throw new CannotDeploySelfError(repositoryPath);
        }
        this.logger.info('[StartApplicationDeploymentUseCase] repository exists, calling deploymentService.start()', { applicationId });
        // Key by applicationId (not repositoryPath) so each application is its
        // own first-class row in `dev_servers` — keeps recovery and the
        // dev-server lifecycle isolated per application even if two apps
        // happened to share a filesystem root.
        this.deploymentService.start(applicationId, repositoryPath, 'application');
        this.logger.info('[StartApplicationDeploymentUseCase] start() returned successfully — state=Booting', { applicationId });
        return { state: DeploymentState.Booting };
    }
};
StartApplicationDeploymentUseCase = __decorate([
    injectable(),
    __param(0, inject('IApplicationRepository')),
    __param(1, inject('IFileSystemService')),
    __param(2, inject('IShepInstanceService')),
    __param(3, inject('IDeploymentService')),
    __param(4, inject('ILogger')),
    __metadata("design:paramtypes", [Object, Object, Object, Object, Object])
], StartApplicationDeploymentUseCase);
export { StartApplicationDeploymentUseCase };
