/**
 * Expo Config Plugin for SQLite Sync Extension
 *
 * This plugin automatically configures iOS and Android to include the SQLite Sync
 * native binaries. Just add "@sqliteai/sqlite-sync-expo-dev" to your app.json plugins.
 *
 * Usage in app.json:
 * {
 *   "expo": {
 *     "plugins": ["@sqliteai/sqlite-sync-expo-dev"]
 *   }
 * }
 */

const {
  withXcodeProject,
  withDangerousMod,
  IOSConfig,
} = require('expo/config-plugins');
const fs = require('fs');
const path = require('path');

// Get the directory where this package is installed
const PACKAGE_ROOT = __dirname;

/**
 * iOS: Add CloudSync.xcframework to the Xcode project
 */
function withSqliteSyncIOS(config) {
  return withXcodeProject(config, (config) => {
    const projectRoot = config.modRequest.projectRoot;
    const projectName = config.modRequest.projectName;
    const xcodeProject = config.modResults;

    // Source path: xcframework bundled with this package
    const srcFrameworkPath = path.join(PACKAGE_ROOT, 'ios', 'CloudSync.xcframework');

    // Destination path: inside the iOS project
    const destFrameworkPath = path.join(
      projectRoot,
      'ios',
      projectName,
      'CloudSync.xcframework'
    );

    // Check source exists
    if (!fs.existsSync(srcFrameworkPath)) {
      throw new Error(
        `CloudSync.xcframework not found at ${srcFrameworkPath}. ` +
        'This is a bug in @sqliteai/sqlite-sync-expo-dev - the package is missing iOS binaries.'
      );
    }

    // Copy xcframework to iOS project directory
    console.log(`[@sqliteai/sqlite-sync-expo-dev] Copying xcframework to ${destFrameworkPath}`);
    fs.cpSync(srcFrameworkPath, destFrameworkPath, { recursive: true });

    // Get the main app target
    const target = IOSConfig.XcodeUtils.getApplicationNativeTarget({
      project: xcodeProject,
      projectName: projectName,
    });

    // Check if "Embed Frameworks" build phase exists, create if not
    const embedFrameworksBuildPhase = xcodeProject.buildPhaseObject(
      'PBXCopyFilesBuildPhase',
      'Embed Frameworks'
    );

    if (!embedFrameworksBuildPhase) {
      console.log('[@sqliteai/sqlite-sync-expo-dev] Creating "Embed Frameworks" build phase');
      xcodeProject.addBuildPhase(
        [],
        'PBXCopyFilesBuildPhase',
        'Embed Frameworks',
        target.uuid,
        'frameworks'
      );
    }

    // Add the framework to the project
    const relativePath = `${projectName}/CloudSync.xcframework`;
    console.log(`[@sqliteai/sqlite-sync-expo-dev] Adding framework: ${relativePath}`);

    xcodeProject.addFramework(relativePath, {
      target: target.uuid,
      customFramework: true,
      embed: true,
      sign: true,
      link: true,
    });

    console.log('[@sqliteai/sqlite-sync-expo-dev] iOS setup complete');
    return config;
  });
}

/**
 * Android: Copy libcloudsync.so files to jniLibs
 */
function withSqliteSyncAndroid(config) {
  return withDangerousMod(config, [
    'android',
    async (config) => {
      const projectRoot = config.modRequest.projectRoot;

      // Source directory: .so files bundled with this package
      const srcDir = path.join(PACKAGE_ROOT, 'android', 'jniLibs');

      // Destination: android/app/src/main/jniLibs
      const jniLibsDir = path.join(
        projectRoot,
        'android',
        'app',
        'src',
        'main',
        'jniLibs'
      );

      // Architectures we support
      const architectures = ['arm64-v8a', 'armeabi-v7a', 'x86_64'];

      for (const arch of architectures) {
        const srcFile = path.join(srcDir, arch, 'cloudsync.so');
        const destDir = path.join(jniLibsDir, arch);
        const destFile = path.join(destDir, 'cloudsync.so');

        // Check source exists
        if (!fs.existsSync(srcFile)) {
          console.warn(
            `[@sqliteai/sqlite-sync-expo-dev] Warning: ${srcFile} not found, skipping ${arch}`
          );
          continue;
        }

        // Create destination directory
        fs.mkdirSync(destDir, { recursive: true });

        // Copy the .so file
        console.log(`[@sqliteai/sqlite-sync-expo-dev] Copying ${arch}/cloudsync.so`);
        fs.copyFileSync(srcFile, destFile);
      }

      console.log('[@sqliteai/sqlite-sync-expo-dev] Android setup complete');
      return config;
    },
  ]);
}

/**
 * Main plugin function - combines iOS and Android plugins
 */
function withSqliteSync(config) {
  console.log('[@sqliteai/sqlite-sync-expo-dev] Configuring SQLite Sync extension...');

  // Apply iOS modifications
  config = withSqliteSyncIOS(config);

  // Apply Android modifications
  config = withSqliteSyncAndroid(config);

  return config;
}

module.exports = withSqliteSync;
