integrateMainFile method

void integrateMainFile(
  1. String path,
  2. FlavorConfig config, {
  3. String? flavor,
})

Implementation

void integrateMainFile(String path, FlavorConfig config, {String? flavor}) {
  final file = File(path);
  if (!file.existsSync()) return;

  var content = file.readAsStringSync();
  final configPath = config.appConfigPath;

  final relativeToRoot = p.relative(path, from: ConfigService.root);
  final relativeConfigPath = p.relative(
    configPath,
    from: p.dirname(relativeToRoot),
  );

  // 1. Add AppConfig import
  if (!content.contains(p.basename(configPath))) {
    content = "import '$relativeConfigPath';\n$content";
  }

  // 2. Add flutter_dotenv import
  if (!content.contains('flutter_dotenv')) {
    content =
        "import 'package:flutter_dotenv/flutter_dotenv.dart';\n$content";
  }

  // 3. Ensure dotenv.load and AppConfig.init are present
  if (!content.contains('dotenv.load')) {
    final mainRegex = RegExp(
      r'(Future<void>|void) main\s*\(\s*\)\s*(async\s*)?{',
    );
    final match = mainRegex.firstMatch(content);
    if (match != null) {
      final String loadCall;
      if (flavor != null) {
        loadCall = "await dotenv.load(fileName: '.env.$flavor');";
      } else {
        loadCall =
            "const flavorString = String.fromEnvironment('FLAVOR');\n  await dotenv.load(fileName: '.env.\$flavorString');";
      }

      final String initCall;
      if (content.contains('AppConfig.init')) {
        initCall = ""; // Already present
      } else {
        initCall = flavor != null
            ? "\n  AppConfig.init(Flavor.$flavor);"
            : "\n  final flavor = _getFlavor(flavorString);\n  AppConfig.init(flavor);";
      }

      // Remove existing ensureInitialized to avoid duplicates and ensure it's at the top
      content = content.replaceAll(
        RegExp(
          r'^\s*WidgetsFlutterBinding\.ensureInitialized\(\);\s*\n?',
          multiLine: true,
        ),
        '',
      );

      content = content.replaceFirst(
        mainRegex,
        "Future<void> main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  $loadCall$initCall",
      );
    }
  } else if (!content.contains('AppConfig.init')) {
    // dotEnv exists but AppConfig.init doesn't? (unlikely but possible)
    final initCall = flavor != null
        ? "AppConfig.init(Flavor.$flavor);"
        : "final flavor = _getFlavor(flavorString);\n  AppConfig.init(flavor);";
    content = content.replaceFirst(
      'dotenv.load(',
      '$initCall\n  dotenv.load(',
    );
  }

  // 4. Ensure _getFlavor helper exists for single main strategy
  if (flavor == null && !content.contains('Flavor _getFlavor')) {
    final flavors = config.flavors;
    final cases =
        flavors.map((f) => "    case '$f': return Flavor.$f;").join('\n');
    final helper = """
Flavor _getFlavor(String flavor) {
switch (flavor) {
$cases
  default: return Flavor.${flavors.first};
}
}
""";
    content = "$content\n$helper";
  }

  file.writeAsStringSync(content);
  FileService.formatFile(path);
}