import { CodeParser } from '../utils/parser.js';
import { EnvironmentDetector } from '../adapters/detector.js';
import { FileOperations } from '../utils/file.js';
export interface DebugInjectionOptions {
filePath: string;
insertLine: number;
logMessage: string;
variables: string[];
level?: 'info' | 'error' | 'debug' | 'warn';
environment?: string;
projectPath?: string; // Optional project path for tool library detection
}
export interface InjectionResult {
success: boolean;
filePath: string;
adapterUsed: string;
injectedCode: string;
modifiedLines: number[];
error?: string;
}
export class DebugInjector {
private parser: CodeParser;
private detector: EnvironmentDetector;
private fileOps: FileOperations;
constructor() {
this.parser = new CodeParser();
this.detector = new EnvironmentDetector();
this.fileOps = new FileOperations();
}
/**
* Insert debug code into a file
*/
injectDebugLogs(options: DebugInjectionOptions): InjectionResult {
const { filePath, insertLine, logMessage, variables, level, environment } = options;
// Read file content
const fileContent = this.fileOps.readFile(filePath);
if (!fileContent) {
return {
success: false,
filePath,
adapterUsed: '',
injectedCode: '',
modifiedLines: [],
error: 'Failed to read file'
};
}
// Detect environment if not specified
let detectedEnv = environment;
if (!detectedEnv) {
const detection = this.detector.detectEnvironment(filePath, fileContent);
detectedEnv = detection.suggestedAdapter;
}
// Generate debug code using appropriate adapter
const debugCode = this.detector.generateDebugCode(filePath, fileContent, {
logMessage,
variables,
level: level || 'info',
environment: detectedEnv,
projectPath: options.projectPath
});
// Create backup before modifying
const backupPath = this.fileOps.createBackup(filePath);
if (backupPath) {
console.error(`[Backup] Created: ${backupPath}`);
}
// Insert debug code
const result = this.parser.insertDebugCode(filePath, debugCode, insertLine);
if (!result.success) {
return {
success: false,
filePath,
adapterUsed: detectedEnv,
injectedCode: debugCode,
modifiedLines: [],
error: 'Failed to insert debug code'
};
}
return {
success: true,
filePath,
adapterUsed: detectedEnv,
injectedCode: debugCode,
modifiedLines: result.modifiedLines
};
}
/**
* Inject multiple debug logs at different locations
*/
injectMultipleDebugLogs(injections: DebugInjectionOptions[]): InjectionResult[] {
return injections.map(injection => this.injectDebugLogs(injection));
}
/**
* Smart injection - automatically determine insertion points
*/
smartInject(
filePath: string,
bugDescription: string,
locations: Array<{ line: number; description: string; variables: string[] }>
): InjectionResult[] {
const results: InjectionResult[] = [];
for (const location of locations) {
const result = this.injectDebugLogs({
filePath,
insertLine: location.line,
logMessage: `${bugDescription} - ${location.description}`,
variables: location.variables,
level: 'info'
});
results.push(result);
}
return results;
}
/**
* List all debug blocks in a file
*/
listDebugBlocks(filePath: string): Array<{
startLine: number;
endLine: number;
content: string;
}> {
return this.parser.findDebugBlocks(filePath);
}
/**
* Get debug code for a specific environment without injecting
*/
generateDebugCode(
filePath: string,
logMessage: string,
variables: string[],
level: 'info' | 'error' | 'debug' | 'warn' = 'info',
projectPath?: string
): string {
const fileContent = this.fileOps.readFile(filePath);
return this.detector.generateDebugCode(filePath, fileContent || '', {
logMessage,
variables,
level,
projectPath
});
}
/**
* Detect environment of a file
*/
detectFileEnvironment(filePath: string): {
environment: string;
confidence: number;
suggestedAdapter: string;
reasoning: string;
} {
const fileContent = this.fileOps.readFile(filePath);
return this.detector.detectEnvironment(filePath, fileContent || '');
}
}