"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDjangoVersionBucket = exports.IGNORE_PATTERNS = exports.DjangoProjectType = void 0;
exports.getDjangoVersion = getDjangoVersion;
exports.getDjangoProjectType = getDjangoProjectType;
exports.getDjangoProjectTypeName = getDjangoProjectTypeName;
exports.findDjangoSettingsFile = findDjangoSettingsFile;
exports.findDjangoUrlsFile = findDjangoUrlsFile;
const fast_glob_1 = __importDefault(require("fast-glob"));
const ui_1 = require("../../ui");
const semver_1 = require("../../utils/semver");
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
var DjangoProjectType;
(function (DjangoProjectType) {
    DjangoProjectType["STANDARD"] = "standard";
    DjangoProjectType["DRF"] = "drf";
    DjangoProjectType["WAGTAIL"] = "wagtail";
    DjangoProjectType["CHANNELS"] = "channels";
})(DjangoProjectType || (exports.DjangoProjectType = DjangoProjectType = {}));
exports.IGNORE_PATTERNS = [
    '**/node_modules/**',
    '**/dist/**',
    '**/build/**',
    '**/venv/**',
    '**/.venv/**',
    '**/env/**',
    '**/.env/**',
    '**/__pycache__/**',
    '**/migrations/**',
];
/**
 * Get Django version bucket for analytics
 */
exports.getDjangoVersionBucket = (0, semver_1.createVersionBucket)();
/**
 * Extract Django version from requirements files or pyproject.toml
 */
async function getDjangoVersion(options) {
    const { installDir } = options;
    // Check requirements files
    const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/setup.py', '**/Pipfile'], {
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    for (const reqFile of requirementsFiles) {
        try {
            const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
            // Try to extract version from requirements.txt format (Django==4.2.0 or Django>=4.0)
            const requirementsMatch = content.match(/[Dd]jango[=<>~!]+([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
            if (requirementsMatch) {
                return requirementsMatch[1];
            }
            // Try to extract from pyproject.toml format
            const pyprojectMatch = content.match(/[Dd]jango["\s]*[=<>~!]+\s*["']?([0-9]+\.[0-9]+(?:\.[0-9]+)?)/);
            if (pyprojectMatch) {
                return pyprojectMatch[1];
            }
        }
        catch {
            // Skip files that can't be read
            continue;
        }
    }
    return undefined;
}
/**
 * Check if Django REST Framework is installed
 */
async function hasDRF({ installDir, }) {
    const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], {
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    for (const reqFile of requirementsFiles) {
        try {
            const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
            if (content.includes('djangorestframework')) {
                return true;
            }
        }
        catch {
            continue;
        }
    }
    // Also check INSTALLED_APPS in settings
    const settingsFiles = await (0, fast_glob_1.default)('**/settings.py', {
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    for (const settingsFile of settingsFiles) {
        try {
            const content = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8');
            if (content.includes('rest_framework')) {
                return true;
            }
        }
        catch {
            continue;
        }
    }
    return false;
}
/**
 * Check if Wagtail is installed
 */
async function hasWagtail({ installDir, }) {
    const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], {
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    for (const reqFile of requirementsFiles) {
        try {
            const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
            if (content.includes('wagtail')) {
                return true;
            }
        }
        catch {
            continue;
        }
    }
    return false;
}
/**
 * Check if Django Channels is installed
 */
async function hasChannels({ installDir, }) {
    const requirementsFiles = await (0, fast_glob_1.default)(['**/requirements*.txt', '**/pyproject.toml', '**/Pipfile'], {
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    for (const reqFile of requirementsFiles) {
        try {
            const content = fs.readFileSync(path.join(installDir, reqFile), 'utf-8');
            if (content.includes('channels')) {
                return true;
            }
        }
        catch {
            continue;
        }
    }
    return false;
}
/**
 * Detect Django project type
 */
async function getDjangoProjectType(options) {
    const { installDir } = options;
    // Check for Wagtail first (CMS)
    if (await hasWagtail({ installDir })) {
        (0, ui_1.getUI)().setDetectedFramework('Django with Wagtail CMS');
        return DjangoProjectType.WAGTAIL;
    }
    // Check for Django REST Framework
    if (await hasDRF({ installDir })) {
        (0, ui_1.getUI)().setDetectedFramework('Django REST Framework');
        return DjangoProjectType.DRF;
    }
    // Check for Django Channels
    if (await hasChannels({ installDir })) {
        (0, ui_1.getUI)().setDetectedFramework('Django Channels');
        return DjangoProjectType.CHANNELS;
    }
    // Default to standard Django
    (0, ui_1.getUI)().setDetectedFramework('Django');
    return DjangoProjectType.STANDARD;
}
/**
 * Get human-readable name for Django project type
 */
function getDjangoProjectTypeName(projectType) {
    switch (projectType) {
        case DjangoProjectType.STANDARD:
            return 'Standard Django';
        case DjangoProjectType.DRF:
            return 'Django REST Framework';
        case DjangoProjectType.WAGTAIL:
            return 'Wagtail CMS';
        case DjangoProjectType.CHANNELS:
            return 'Django Channels';
    }
}
/**
 * Find the main Django settings file
 */
async function findDjangoSettingsFile(options) {
    const { installDir } = options;
    // Look for settings.py files
    const settingsFiles = await (0, fast_glob_1.default)('**/settings.py', {
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    if (settingsFiles.length === 0) {
        // Try settings/__init__.py for split settings
        const splitSettingsFiles = await (0, fast_glob_1.default)('**/settings/__init__.py', {
            cwd: installDir,
            ignore: exports.IGNORE_PATTERNS,
        });
        if (splitSettingsFiles.length > 0) {
            return splitSettingsFiles[0];
        }
        return undefined;
    }
    // If multiple settings files, prefer the one next to manage.py or in root
    if (settingsFiles.length === 1) {
        return settingsFiles[0];
    }
    // Try to find the main settings file by looking for ROOT_URLCONF
    for (const settingsFile of settingsFiles) {
        try {
            const content = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8');
            if (content.includes('ROOT_URLCONF')) {
                return settingsFile;
            }
        }
        catch {
            continue;
        }
    }
    // Default to first found
    return settingsFiles[0];
}
/**
 * Find the main Django urls.py file
 */
async function findDjangoUrlsFile(options) {
    const { installDir } = options;
    // First, try to find the root urls.py referenced in settings
    const settingsFile = await findDjangoSettingsFile(options);
    if (settingsFile) {
        try {
            const settingsContent = fs.readFileSync(path.join(installDir, settingsFile), 'utf-8');
            const urlconfMatch = settingsContent.match(/ROOT_URLCONF\s*=\s*['"]([^'"]+)['"]/);
            if (urlconfMatch) {
                const urlconfPath = urlconfMatch[1].replace(/\./g, '/') + '.py';
                const fullPath = path.join(installDir, urlconfPath);
                if (fs.existsSync(fullPath)) {
                    return urlconfPath;
                }
            }
        }
        catch {
            // Fall through to glob search
        }
    }
    // Fallback to glob search
    const urlsFiles = await (0, fast_glob_1.default)('**/urls.py', {
        cwd: installDir,
        ignore: [...exports.IGNORE_PATTERNS, '**/admin/**'],
    });
    if (urlsFiles.length === 0) {
        return undefined;
    }
    // Prefer urls.py files that contain urlpatterns
    for (const urlsFile of urlsFiles) {
        try {
            const content = fs.readFileSync(path.join(installDir, urlsFile), 'utf-8');
            if (content.includes('urlpatterns')) {
                return urlsFile;
            }
        }
        catch {
            continue;
        }
    }
    return urlsFiles[0];
}
