/*
 * 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 { createHash } from 'node:crypto';
import { execFileSync } from 'node:child_process';
import { existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
/**
 * Determines which files have changed since the last index generation.
 * Returns the set of relative file paths that need re-indexing.
 */
export function getChangedFiles(cwd, sourceDir, mode) {
    if (mode === 'full')
        return null; // null signals full scan
    if (mode === 'git-diff') {
        return getGitDiffFiles(cwd, sourceDir);
    }
    // hash-compare requires an existing index to compare against
    return getHashChangedFiles(cwd, sourceDir);
}
/**
 * Computes a content hash for a file. Used for hash-compare delta mode.
 */
export function computeFileHash(filePath) {
    const content = readFileSync(filePath, 'utf8');
    return createHash('sha256').update(content).digest('hex').slice(0, 12);
}
function getGitDiffFiles(cwd, sourceDir) {
    try {
        const output = execFileSync('git', ['diff', '--name-only', 'HEAD~1', 'HEAD', '--', sourceDir], {
            cwd,
            encoding: 'utf8',
        });
        const files = output
            .split('\n')
            .map((f) => f.trim())
            .filter((f) => f.length > 0);
        // Also include untracked/staged files
        const statusOutput = execFileSync('git', ['status', '--porcelain', '--', sourceDir], {
            cwd,
            encoding: 'utf8',
        });
        const statusFiles = statusOutput
            .split('\n')
            .map((line) => line.slice(3).trim())
            .filter((f) => f.length > 0);
        const allFiles = new Set([...files, ...statusFiles]);
        return [...allFiles];
    }
    catch {
        // If git commands fail, fall back to full scan
        return null;
    }
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function getHashChangedFiles(cwd, sourceDir) {
    const indexPath = join(cwd, '.setup-agents', 'sf-metadata-index.json');
    if (!existsSync(indexPath))
        return null; // No previous index, do full scan
    try {
        const existing = JSON.parse(readFileSync(indexPath, 'utf8'));
        const previousHashes = new Map();
        for (const entry of existing.entries) {
            if (entry.hash) {
                previousHashes.set(entry.path, entry.hash);
            }
        }
        const changed = [];
        for (const [path, prevHash] of previousHashes) {
            const fullPath = join(cwd, path);
            if (!existsSync(fullPath)) {
                changed.push(path);
                continue;
            }
            const currentHash = computeFileHash(fullPath);
            if (currentHash !== prevHash) {
                changed.push(path);
            }
        }
        return changed.length > 0 ? changed : [];
    }
    catch {
        return null;
    }
}
//# sourceMappingURL=delta-engine.js.map