package expo.modules.interfaces.taskManager

import android.content.Context
import expo.modules.core.ModulePriorities
import expo.modules.core.interfaces.DoNotStrip
import expo.modules.core.interfaces.Package

@DoNotStrip
object TaskServiceProviderHelper {
  /**
   Uses reflection to look through the current list of packages and attempts to find
   one that provides a TaskServiceInterface implementation.
   @param context Provide the application context (context.getApplicationContext())
   @return A implementation of the TaskServiceInterface it a package offers it
   */
  @DoNotStrip
  fun getTaskServiceImpl(context: Context): TaskServiceInterface? {
    // Use reflection to get the packages list from ExpoModulesPackageList without
    // creating the reactInstanceManager. ExpoModulesPackageList is generated by
    // autolinking and should safely be callable in this way - we already have a
    // few other places in our code where it is called like this.
    val expoModules: Class<*>? = try {
      Class.forName("expo.modules.ExpoModulesPackageList")
    } catch (e: ClassNotFoundException) {
      // Handle the exception, e.g., log it or fallback to a default behavior
      return null
    }
    val getPackageList = expoModules?.getMethod("getPackageList") ?: return null

    // Invoke and get the list of packages
    val result = getPackageList.invoke(null) as? List<*> ?: return null
    val packages = result.filterIsInstance<Package>()
      .sortedByDescending { ModulePriorities.get(it::class.qualifiedName) }

    // Check if any of the packages are providing a task manager implementation
    return packages
      .filterIsInstance<TaskServiceProviderInterface>()
      .firstOrNull()
      ?.getTaskServiceImpl(context)
  }
}
