import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { afterEach, describe, expect, it } from 'vitest';
import { resolveBridgePackageEntryPath } from './sdk-package-loader.js';
const tempRoots = [];
afterEach(async () => {
    await Promise.all(tempRoots.splice(0).map((root) => rm(root, { recursive: true, force: true })));
});
async function createTempPackageRoot() {
    const root = await mkdtemp(path.join(os.tmpdir(), 'aws-sdk-package-loader-'));
    tempRoots.push(root);
    return root;
}
describe('sdk package loader', () => {
    it('resolves package exports instead of assuming a root index.js file', async () => {
        const packageRoot = await createTempPackageRoot();
        const packageDirectory = path.join(packageRoot, 'node_modules', '@opencode-ai', 'sdk');
        await mkdir(path.join(packageDirectory, 'dist'), { recursive: true });
        await writeFile(path.join(packageDirectory, 'package.json'), JSON.stringify({
            name: '@opencode-ai/sdk',
            type: 'module',
            exports: {
                '.': {
                    import: './dist/index.js',
                    types: './dist/index.d.ts',
                },
            },
        }));
        await writeFile(path.join(packageDirectory, 'dist', 'index.js'), 'export const ok = true;');
        await expect(resolveBridgePackageEntryPath('@opencode-ai/sdk', packageRoot)).resolves.toBe(path.join(packageDirectory, 'dist', 'index.js'));
    });
    it('resolves default conditional exports', async () => {
        const packageRoot = await createTempPackageRoot();
        const packageDirectory = path.join(packageRoot, 'node_modules', 'default-only-sdk');
        await mkdir(path.join(packageDirectory, 'dist'), { recursive: true });
        await writeFile(path.join(packageDirectory, 'package.json'), JSON.stringify({ exports: { '.': { default: './dist/default.js' } } }));
        await writeFile(path.join(packageDirectory, 'dist', 'default.js'), 'export const ok = true;');
        await expect(resolveBridgePackageEntryPath('default-only-sdk', packageRoot)).resolves.toBe(path.join(packageDirectory, 'dist', 'default.js'));
    });
    it('resolves Claude Agent SDK default export to sdk.mjs', async () => {
        const packageRoot = await createTempPackageRoot();
        const packageDirectory = path.join(packageRoot, 'node_modules', '@anthropic-ai', 'claude-agent-sdk');
        await mkdir(packageDirectory, { recursive: true });
        await writeFile(path.join(packageDirectory, 'package.json'), JSON.stringify({
            name: '@anthropic-ai/claude-agent-sdk',
            type: 'module',
            main: 'sdk.mjs',
            exports: {
                '.': {
                    types: './sdk.d.ts',
                    default: './sdk.mjs',
                },
            },
        }));
        await writeFile(path.join(packageDirectory, 'sdk.mjs'), 'export const query = () => {};');
        await expect(resolveBridgePackageEntryPath('@anthropic-ai/claude-agent-sdk', packageRoot)).resolves.toBe(path.join(packageDirectory, 'sdk.mjs'));
    });
    it('falls back to module when exports is absent', async () => {
        const packageRoot = await createTempPackageRoot();
        const packageDirectory = path.join(packageRoot, 'node_modules', 'module-sdk');
        await mkdir(path.join(packageDirectory, 'esm'), { recursive: true });
        await writeFile(path.join(packageDirectory, 'package.json'), JSON.stringify({ module: './esm/index.js' }));
        await writeFile(path.join(packageDirectory, 'esm', 'index.js'), 'export const ok = true;');
        await expect(resolveBridgePackageEntryPath('module-sdk', packageRoot)).resolves.toBe(path.join(packageDirectory, 'esm', 'index.js'));
    });
    it('falls back to main when exports and module are absent', async () => {
        const packageRoot = await createTempPackageRoot();
        const packageDirectory = path.join(packageRoot, 'node_modules', 'main-sdk');
        await mkdir(path.join(packageDirectory, 'lib'), { recursive: true });
        await writeFile(path.join(packageDirectory, 'package.json'), JSON.stringify({ main: './lib/main.js' }));
        await writeFile(path.join(packageDirectory, 'lib', 'main.js'), 'export const ok = true;');
        await expect(resolveBridgePackageEntryPath('main-sdk', packageRoot)).resolves.toBe(path.join(packageDirectory, 'lib', 'main.js'));
    });
    it('rejects when the resolved package entry is missing', async () => {
        const packageRoot = await createTempPackageRoot();
        const packageDirectory = path.join(packageRoot, 'node_modules', 'broken-sdk');
        await mkdir(packageDirectory, { recursive: true });
        await writeFile(path.join(packageDirectory, 'package.json'), JSON.stringify({ exports: './dist/missing.js' }));
        await expect(resolveBridgePackageEntryPath('broken-sdk', packageRoot)).rejects.toMatchObject({
            code: 'ENOENT',
        });
    });
});
