/*
 * Copyright 2026, Jaime Terrats.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { Messages } from '@salesforce/core';
import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
import { checkAllDependencies, DEPENDENCY_REGISTRY } from '../../services/dependency-check.js';
import { dedupeById } from '../../services/file-writer.js';
import { listRecords } from '../../services/orchestration-records.js';
import { listTasks } from '../../services/task-state.js';
import { resolvePhaseInstructions, resolvePhaseSequence } from '../../services/workflow-instructions.js';
import { getWorkspaceConfigPath, readWorkspaceConfig } from '../../services/workspace-config.js';
import { findStaleFiles } from '../../util/command-helpers.js';
import { PLUGIN_VERSION } from '../../version.js';
import Update from './update.js';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@jterrats/setup-agents', 'setup-agents.status');
export default class Status extends SfCommand {
    static summary = messages.getMessage('summary');
    static description = messages.getMessage('description');
    static examples = messages.getMessages('examples');
    static flags = {
        fix: Flags.boolean({
            summary: messages.getMessage('flags.fix.summary'),
            default: false,
        }),
    };
    async run() {
        const { flags } = await this.parse(Status);
        const cwd = process.cwd();
        const config = readWorkspaceConfig(cwd);
        const configFile = config ? getWorkspaceConfigPath(cwd) : null;
        const tasks = listTasks(cwd);
        const openTasks = tasks.filter((t) => t.status === 'open').length;
        const claimedTasks = tasks.filter((t) => t.status === 'claimed').length;
        const doneTasks = tasks.filter((t) => t.status === 'done').length;
        const reviews = listRecords(cwd, 'review');
        const latestReviews = dedupeById(reviews);
        const pendingReviews = latestReviews.filter((r) => r.status === 'pending').length;
        const handoffs = listRecords(cwd, 'handoff');
        const evidenceIds = new Set(listRecords(cwd, 'evidence').map((e) => e.id));
        const blockedHandoffs = handoffs.filter((h) => h.evidenceIds && h.evidenceIds.length > 0 && !h.evidenceIds.every((id) => evidenceIds.has(id))).length;
        const claimedWithoutEvidence = tasks.filter((t) => t.status === 'claimed' && t.evidenceIds.length === 0).length;
        // Rules health: reuse findStaleFiles to detect outdated rule files per profile
        const staleFiles = findStaleFiles(cwd);
        const staleSet = new Set(staleFiles.map((f) => f.file));
        const rulesHealth = staleFiles.map((f) => ({
            profile: f.file,
            file: f.file,
            embeddedVersion: f.version,
            pluginVersion: PLUGIN_VERSION,
            stale: true,
        }));
        // Playbook health: only meaningful when workspace is configured with profiles
        const activeProfiles = config?.profiles ?? [];
        const playbookHealth = config
            ? resolvePhaseSequence(activeProfiles).flatMap((phase) => {
                const instructions = resolvePhaseInstructions(cwd, phase);
                return instructions.playbooks.map((pb) => ({
                    phase,
                    file: pb.filename,
                    exists: pb.exists,
                }));
            })
            : [];
        const depCheck = checkAllDependencies();
        const dependencyHealth = depCheck.dependencies.map((d) => {
            const descriptor = DEPENDENCY_REGISTRY.find((r) => r.id === d.id);
            return {
                id: d.id,
                label: descriptor.label,
                installed: d.installed,
                version: d.version,
                optional: descriptor.optional,
            };
        });
        const result = {
            openTasks,
            claimedTasks,
            doneTasks,
            pendingReviews,
            blockedHandoffs,
            missingEvidence: claimedWithoutEvidence,
            configFile,
            mode: config?.mode ?? null,
            profiles: activeProfiles,
            cwd,
            rulesHealth,
            playbookHealth,
            dependencyHealth,
        };
        this.log(messages.getMessage('info.header'));
        this.log(messages.getMessage('info.workspace', [
            config ? `${config.mode} (${config.profiles.join(', ')})` : 'not configured',
        ]));
        this.log(messages.getMessage('info.tasks', [openTasks, claimedTasks, doneTasks]));
        this.log(messages.getMessage('info.reviews', [pendingReviews]));
        this.log(messages.getMessage('info.handoffs', [blockedHandoffs]));
        this.log(messages.getMessage('info.evidence', [claimedWithoutEvidence]));
        this.logRulesHealth(staleFiles, staleSet.size, playbookHealth);
        this.logDependencyHealth(depCheck);
        if (flags.fix && staleSet.size > 0) {
            this.log('Running sf setup-agents update...');
            await Update.run([]);
        }
        return result;
    }
    logRulesHealth(staleFiles, staleRuleCount, playbookHealth) {
        const missingPlaybooks = playbookHealth.filter((p) => !p.exists).length;
        if (staleRuleCount === 0 && missingPlaybooks === 0) {
            this.log('Rules Health: ✅ All rule files up to date, all playbooks present');
            return;
        }
        if (staleRuleCount > 0) {
            this.log(`Rules Health: ⚠ ${staleRuleCount} stale rule file(s) detected — run: sf setup-agents update`);
            for (const f of staleFiles) {
                this.log(`  stale: ${f.file} (embedded: ${f.version ?? 'none'}, current: ${PLUGIN_VERSION})`);
            }
        }
        if (missingPlaybooks > 0) {
            this.log(`Playbooks: ⚠ ${missingPlaybooks} missing — run: sf setup-agents workflow playbooks --scaffold`);
            for (const p of playbookHealth.filter((pb) => !pb.exists)) {
                this.log(`  missing: [${p.phase}] ${p.file}`);
            }
        }
    }
    logDependencyHealth(depCheck) {
        const missingRequired = depCheck.missing.filter((d) => !DEPENDENCY_REGISTRY.find((r) => r.id === d.id)?.optional);
        const missingOptional = depCheck.missing.filter((d) => DEPENDENCY_REGISTRY.find((r) => r.id === d.id)?.optional);
        if (missingRequired.length === 0 && missingOptional.length === 0) {
            this.log('Dependencies: ✅ All detected');
            return;
        }
        if (missingRequired.length > 0) {
            this.log(`Dependencies: ❌ ${missingRequired.length} required missing`);
            for (const d of missingRequired) {
                const desc = DEPENDENCY_REGISTRY.find((r) => r.id === d.id);
                this.log(`  missing (required): ${desc.label} — ${desc.installCommand || desc.installHint}`);
            }
        }
        if (missingOptional.length > 0) {
            this.log(`Dependencies: ⚠ ${missingOptional.length} optional missing`);
            for (const d of missingOptional) {
                const desc = DEPENDENCY_REGISTRY.find((r) => r.id === d.id);
                this.log(`  missing (optional): ${desc.label} — ${desc.purpose}`);
            }
        }
    }
}
//# sourceMappingURL=status.js.map