"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.getNextJsRouterName = exports.IGNORE_PATTERNS = exports.NextJsRouter = exports.getNextJsVersionBucket = void 0;
exports.getNextJsRouter = getNextJsRouter;
exports.detectNextJsSurfaces = detectNextJsSurfaces;
const fast_glob_1 = __importDefault(require("fast-glob"));
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
const semver_1 = require("../../utils/semver");
exports.getNextJsVersionBucket = (0, semver_1.createVersionBucket)();
var NextJsRouter;
(function (NextJsRouter) {
    NextJsRouter["APP_ROUTER"] = "app-router";
    NextJsRouter["PAGES_ROUTER"] = "pages-router";
})(NextJsRouter || (exports.NextJsRouter = NextJsRouter = {}));
exports.IGNORE_PATTERNS = [
    '**/node_modules/**',
    '**/dist/**',
    '**/build/**',
    '**/public/**',
    '**/.next/**',
];
/**
 * Detect Next.js router type. Pure — returns null if ambiguous.
 */
async function getNextJsRouter({ installDir, }) {
    const pagesMatches = await (0, fast_glob_1.default)('**/pages/_app.@(ts|tsx|js|jsx)', {
        dot: true,
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    const hasPagesDir = pagesMatches.length > 0;
    const appMatches = await (0, fast_glob_1.default)('**/app/**/layout.@(ts|tsx|js|jsx)', {
        dot: true,
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    const hasAppDir = appMatches.length > 0;
    if (hasPagesDir && !hasAppDir) {
        return NextJsRouter.PAGES_ROUTER;
    }
    if (hasAppDir && !hasPagesDir) {
        return NextJsRouter.APP_ROUTER;
    }
    // Ambiguous (both or neither) — return null, SetupScreen handles it
    return null;
}
const getNextJsRouterName = (router) => {
    return router === NextJsRouter.APP_ROUTER ? 'app router' : 'pages router';
};
exports.getNextJsRouterName = getNextJsRouterName;
async function detectNextJsSurfaces({ installDir, }) {
    // App Router pages: any file matching `<root>/app/**/page.{ts,tsx,js,jsx}`
    // or `src/app/**/page.{...}`. layout.tsx alone doesn't render content.
    const appPagesMatches = await (0, fast_glob_1.default)('**/app/**/page.@(ts|tsx|js|jsx)', {
        dot: true,
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    // Pages Router pages: anything under pages/ that's NOT under pages/api,
    // and isn't a Next.js framework file (_app/_document/_error/_*). We scan
    // both `pages/` and `src/pages/` for either layout.
    const pagesAllMatches = await (0, fast_glob_1.default)('**/pages/**/*.@(ts|tsx|js|jsx)', {
        dot: true,
        cwd: installDir,
        ignore: exports.IGNORE_PATTERNS,
    });
    const browserPagesMatches = pagesAllMatches.filter((p) => {
        // Drop anything under any pages/api/ subtree
        if (/(^|\/)pages\/api\//.test(p))
            return false;
        // Drop framework files: pages/_app, pages/_document, pages/_error, pages/_*
        const base = path.basename(p);
        if (base.startsWith('_'))
            return false;
        return true;
    });
    const hasBrowserSurface = appPagesMatches.length > 0 || browserPagesMatches.length > 0;
    // Server surfaces:
    //   App Router: app/**/route.{ts,tsx,js,jsx}
    //   Pages Router: pages/api/**/*.{ts,tsx,js,jsx}
    //   Either: middleware.{ts,js} (root or src/)
    const [appRoutes, apiRoutes, middlewareFiles] = await Promise.all([
        (0, fast_glob_1.default)('**/app/**/route.@(ts|tsx|js|jsx)', {
            dot: true,
            cwd: installDir,
            ignore: exports.IGNORE_PATTERNS,
        }),
        (0, fast_glob_1.default)('**/pages/api/**/*.@(ts|tsx|js|jsx)', {
            dot: true,
            cwd: installDir,
            ignore: exports.IGNORE_PATTERNS,
        }),
        (0, fast_glob_1.default)('{,src/}middleware.@(ts|js)', {
            dot: true,
            cwd: installDir,
            ignore: exports.IGNORE_PATTERNS,
        }),
    ]);
    const hasServerSurface = appRoutes.length > 0 || apiRoutes.length > 0 || middlewareFiles.length > 0;
    // src/ layout heuristic — Next.js officially supports either `src/pages`,
    // `src/app`, or any code under `src/` while leaving config at the root.
    // We treat the project as src-layout if either route directory or any
    // common code directory lives under `src/`.
    const srcCandidates = ['pages', 'app', 'lib', 'components'];
    const usesSrcDir = srcCandidates.some((sub) => {
        try {
            return fs.statSync(path.join(installDir, 'src', sub)).isDirectory();
        }
        catch {
            return false;
        }
    });
    return { hasBrowserSurface, hasServerSurface, usesSrcDir };
}
