/*
 * Copyright (c) 2025, Salesforce, Inc.
 * SPDX-License-Identifier: Apache-2
 * For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
 */
/**
 * dw.json configuration file loading.
 *
 * This module provides utilities for loading B2C Commerce configuration from
 * dw.json files, the standard configuration format used by B2C development tools.
 *
 * @module config
 */
import * as fs from 'node:fs';
import * as path from 'node:path';
import { getLogger } from '../logging/logger.js';
/**
 * Finds dw.json by searching upward from the starting directory.
 *
 * @param startDir - Directory to start searching from (defaults to cwd)
 * @returns Path to dw.json if found, undefined otherwise
 *
 * @example
 * const dwPath = findDwJson();
 * if (dwPath) {
 *   console.log(`Found dw.json at ${dwPath}`);
 * }
 */
export function findDwJson(startDir = process.cwd()) {
    let dir = startDir;
    const root = path.parse(dir).root;
    while (dir !== root) {
        const dwJsonPath = path.join(dir, 'dw.json');
        if (fs.existsSync(dwJsonPath)) {
            return dwJsonPath;
        }
        dir = path.dirname(dir);
    }
    return undefined;
}
/**
 * Selects the appropriate config from a multi-config dw.json.
 *
 * Selection priority:
 * 1. Named instance (if `instance` option provided)
 * 2. Config marked as `active: true`
 * 3. Root-level config
 */
function selectConfig(json, instanceName) {
    const logger = getLogger();
    // Single config or no configs array
    if (!Array.isArray(json.configs) || json.configs.length === 0) {
        logger.trace({ selection: 'root', instanceName: json.name }, `[DwJsonSource] Selected config "${json.name ?? 'root'}" (single config)`);
        return json;
    }
    // Find by instance name
    if (instanceName) {
        // Check root first
        if (json.name === instanceName) {
            logger.trace({ selection: 'named', instanceName }, `[DwJsonSource] Selected config "${instanceName}" by name (root)`);
            return json;
        }
        // Then check configs array
        const found = json.configs.find((c) => c.name === instanceName);
        if (found) {
            logger.trace({ selection: 'named', instanceName }, `[DwJsonSource] Selected config "${instanceName}" by name`);
            return found;
        }
        // Instance explicitly requested but not found - return undefined
        logger.trace({ requestedInstance: instanceName }, `[DwJsonSource] Named instance "${instanceName}" not found`);
        return undefined;
    }
    // Find active config
    if (json.active === false) {
        // Root is inactive, look for active in configs
        const activeConfig = json.configs.find((c) => c.active === true);
        if (activeConfig) {
            logger.trace({ selection: 'active', instanceName: activeConfig.name }, `[DwJsonSource] Selected config "${activeConfig.name}" by active flag`);
            return activeConfig;
        }
    }
    // Default to root config
    logger.trace({ selection: 'root', instanceName: json.name }, `[DwJsonSource] Selected config "${json.name ?? 'root'}" (default to root)`);
    return json;
}
/**
 * Loads configuration from a dw.json file.
 *
 * If an explicit path is provided, uses that file. Otherwise, looks for dw.json
 * in the startDir (or cwd). Does NOT search parent directories.
 *
 * Use `findDwJson()` if you need to search upward through parent directories.
 *
 * @param options - Loading options
 * @returns The parsed config with its path, or undefined if no dw.json found
 *
 * @example
 * // Load from ./dw.json (current directory)
 * const result = loadDwJson();
 * if (result) {
 *   console.log(`Loaded from ${result.path}`);
 *   console.log(result.config.hostname);
 * }
 *
 * // Load from specific directory
 * const result = loadDwJson({ startDir: '/path/to/project' });
 *
 * // Use named instance
 * const result = loadDwJson({ instance: 'staging' });
 *
 * // Explicit path
 * const result = loadDwJson({ path: './config/dw.json' });
 */
export function loadDwJson(options = {}) {
    const logger = getLogger();
    // If explicit path provided, use it. Otherwise default to ./dw.json (no upward search)
    const dwJsonPath = options.path ?? path.join(options.startDir || process.cwd(), 'dw.json');
    logger.trace({ path: dwJsonPath }, '[DwJsonSource] Checking for config file');
    if (!fs.existsSync(dwJsonPath)) {
        logger.trace({ path: dwJsonPath }, '[DwJsonSource] No config file found');
        return undefined;
    }
    try {
        const content = fs.readFileSync(dwJsonPath, 'utf8');
        const json = JSON.parse(content);
        const config = selectConfig(json, options.instance);
        if (!config) {
            return undefined;
        }
        return {
            config,
            path: dwJsonPath,
        };
    }
    catch (error) {
        // Invalid JSON or read error
        const message = error instanceof Error ? error.message : String(error);
        logger.trace({ path: dwJsonPath, error: message }, '[DwJsonSource] Failed to parse config file');
        return undefined;
    }
}
//# sourceMappingURL=dw-json.js.map