import { SystemTaskExecutionError } from '../runSystemTask.js';
export function createRelayRuntimeStatusTaskKind(deps) {
    return {
        async run(ctx) {
            const parsed = parseRelayRuntimeTaskParams(ctx.params);
            ctx.emit({
                type: 'progress',
                stepId: 'relay.status.inspect',
                message: 'Inspecting relay runtime',
            });
            const snapshot = await deps.readStatus(parsed);
            ctx.emit({
                type: 'progress',
                stepId: 'relay.status.health',
                message: 'Checking relay runtime health',
            });
            return await buildRelayRuntimeStatusResult(snapshot, deps.checkHealth);
        },
    };
}
export function createRelayRuntimeInstallOrUpdateTaskKind(deps) {
    return {
        async run(ctx) {
            const parsed = parseRelayRuntimeTaskParams(ctx.params);
            ctx.emit({
                type: 'progress',
                stepId: 'relay.install',
                message: 'Installing relay runtime',
            });
            return await deps.installOrUpdate(parsed);
        },
    };
}
export function createRelayRuntimeStartTaskKind(deps) {
    return {
        async run(ctx) {
            const parsed = parseRelayRuntimeTaskParams(ctx.params);
            ctx.emit({
                type: 'progress',
                stepId: 'relay.start',
                message: 'Starting relay runtime',
            });
            await deps.control({
                ...parsed,
                action: 'start',
            });
            ctx.emit({
                type: 'progress',
                stepId: 'relay.status.inspect',
                message: 'Inspecting relay runtime',
            });
            const snapshot = await deps.readStatus(parsed);
            ctx.emit({
                type: 'progress',
                stepId: 'relay.status.health',
                message: 'Checking relay runtime health',
            });
            return await buildRelayRuntimeStatusResult(snapshot, deps.checkHealth);
        },
    };
}
export function createRelayRuntimeStopTaskKind(deps) {
    return {
        async run(ctx) {
            const parsed = parseRelayRuntimeTaskParams(ctx.params);
            ctx.emit({
                type: 'progress',
                stepId: 'relay.stop',
                message: 'Stopping relay runtime',
            });
            await deps.control({
                ...parsed,
                action: 'stop',
            });
            return {
                stopped: true,
            };
        },
    };
}
async function buildRelayRuntimeStatusResult(snapshot, checkHealth) {
    const healthy = typeof snapshot.healthy === 'boolean'
        ? snapshot.healthy
        : await checkHealth({ baseUrl: snapshot.baseUrl });
    return {
        installed: snapshot.installed,
        version: snapshot.version,
        relayUrl: snapshot.baseUrl,
        healthy,
        service: snapshot.service,
    };
}
export function parseRelayRuntimeTaskParams(params) {
    if (!params || typeof params !== 'object' || Array.isArray(params)) {
        throw new SystemTaskExecutionError('invalid_params', 'Invalid relay runtime params.');
    }
    const value = params;
    const target = value.target;
    if (!target || typeof target !== 'object' || Array.isArray(target)) {
        throw new SystemTaskExecutionError('invalid_params', 'Invalid relay runtime target.');
    }
    const targetRecord = target;
    const kind = targetRecord.kind === 'ssh' ? 'ssh' : 'local';
    const channel = value.channel === 'preview' || value.channel === 'dev' ? value.channel : 'stable';
    const mode = value.mode === 'system' ? 'system' : 'user';
    const env = typeof value.env === 'object' && value.env && !Array.isArray(value.env)
        ? Object.fromEntries(Object.entries(value.env).map(([key, innerValue]) => [key, String(innerValue ?? '')]))
        : undefined;
    const selfHostRelayBinaryOverride = typeof value.selfHostRelayBinaryOverride === 'string'
        ? value.selfHostRelayBinaryOverride
        : undefined;
    return {
        target: kind === 'local'
            ? { kind: 'local' }
            : {
                kind: 'ssh',
                ssh: parseSystemTaskSshConfig(targetRecord.ssh),
            },
        channel,
        mode,
        ...(env ? { env } : {}),
        ...(selfHostRelayBinaryOverride ? { selfHostRelayBinaryOverride } : {}),
    };
}
export function parseSystemTaskSshConfig(value) {
    if (!value || typeof value !== 'object' || Array.isArray(value)) {
        throw new SystemTaskExecutionError('invalid_params', 'Invalid ssh config.');
    }
    const record = value;
    const auth = record.auth === 'keyfile' ? 'keyfile' : 'agent';
    return {
        target: ensureNonEmptyString(record.target, 'ssh.target'),
        ...(typeof record.port === 'number' ? { port: record.port } : {}),
        auth,
        ...(typeof record.identityFile === 'string' ? { identityFile: record.identityFile } : {}),
        ...(typeof record.sshConfigFile === 'string' ? { sshConfigFile: record.sshConfigFile } : {}),
        ...(typeof record.knownHostsPath === 'string' ? { knownHostsPath: record.knownHostsPath } : {}),
        ...(typeof record.trustedHostKey === 'string' ? { trustedHostKey: record.trustedHostKey } : {}),
    };
}
function ensureNonEmptyString(value, field) {
    const text = typeof value === 'string' ? value.trim() : '';
    if (!text) {
        throw new SystemTaskExecutionError('invalid_params', `Missing ${field}.`);
    }
    return text;
}
//# sourceMappingURL=relayRuntimeKinds.js.map