export const ImportDriver = {
    /**
     * Add named imports to a source file.
     * If the module path already exists, appends to the existing import.
     * Avoids duplicates.
     */
    createImportItems(sourceFile, modulePath, items) {
        const itemsToImport = ImportDriver.getUniqueImportItems(sourceFile, items);
        const existingPaths = ImportDriver.getImportPaths(sourceFile);
        if (itemsToImport.length === 0)
            return;
        if (existingPaths.includes(modulePath)) {
            const importDecl = sourceFile.getImportDeclaration(modulePath);
            const checked = [];
            for (const item of itemsToImport) {
                const alreadyImported = importDecl
                    ?.getNamedImports()
                    .some((ni) => ni.getName() === item);
                if (!alreadyImported)
                    checked.push(item);
            }
            if (checked.length > 0)
                importDecl?.addNamedImports(checked);
        }
        else {
            sourceFile.addImportDeclaration({
                moduleSpecifier: modulePath,
                namedImports: itemsToImport,
            });
        }
    },
    getImportedDeclarations(sourceFile) {
        return sourceFile
            .getImportDeclarations()
            .flatMap((i) => i.getNamedImports().map((ni) => ni.getName()));
    },
    getImportPaths(sourceFile) {
        return sourceFile
            .getImportDeclarations()
            .map((i) => i.getModuleSpecifier().getLiteralValue());
    },
    getUniqueImportItems(sourceFile, items) {
        const imported = new Set(sourceFile
            .getImportDeclarations()
            .flatMap((i) => i.getNamedImports().map((j) => j.getName())));
        return items.filter((item) => !imported.has(item));
    },
    hasImportDeclaration(sourceFile, declaration) {
        return ImportDriver.getImportedDeclarations(sourceFile).includes(declaration);
    },
};
