import java.nio.file.Paths
import groovy.json.JsonSlurper
import org.gradle.internal.os.OperatingSystem

if (!System.getenv("REACT_NATIVE_OVERRIDE_HERMES_DIR")) {
    throw new GradleException([
        "React Native Node-API needs a custom version of Hermes with Node-API enabled.",
        "Run the following in your Bash- or Zsh-compatible terminal, to clone Hermes and instruct React Native to use it:",
        "",
        "export REACT_NATIVE_OVERRIDE_HERMES_DIR=\$(npx react-native-node-api vendor-hermes --silent)",
        "",
        "And follow this guide to build React Native from source:",
        "https://reactnative.dev/contributing/how-to-build-from-source#update-your-project-to-build-from-source"
    ].join('\n'))
}

def findWeakNodeApiDir() {
    def searchDir = rootDir.toPath()
    do {
        def p = searchDir.resolve("node_modules/weak-node-api")
        if (p.toFile().exists()) {
            return p.toRealPath().toString()
        }
    } while (searchDir = searchDir.getParent())
    throw new GradleException("Could not find `weak-node-api`");
}

buildscript {
  ext.getExtOrDefault = {name ->
    return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['NodeApiModules_' + name]
  }

  repositories {
    google()
    mavenCentral()
  }

  dependencies {
    classpath "com.android.tools.build:gradle:8.7.2"
    // noinspection DifferentKotlinGradleVersion
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
  }
}

def reactNativeArchitectures() {
  def value = rootProject.getProperties().get("reactNativeArchitectures")
  return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
}

apply plugin: "com.android.library"
apply plugin: "kotlin-android"

apply plugin: "com.facebook.react"

def getExtOrIntegerDefault(name) {
  return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["NodeApiModules_" + name]).toInteger()
}

def supportsNamespace() {
  def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
  def major = parsed[0].toInteger()
  def minor = parsed[1].toInteger()

  // Namespace support was added in 7.3.0
  return (major == 7 && minor >= 3) || major >= 8
}

android {
  if (supportsNamespace()) {
    namespace "com.callstack.react_native_node_api"

    sourceSets {
      main {
        manifest.srcFile "src/main/AndroidManifestNew.xml"
        // Include the weak-node-api native libraries directly
        jniLibs.srcDirs += [
          "../../weak-node-api/build/Debug/weak-node-api.android.node",
          "../../weak-node-api/build/Release/weak-node-api.android.node"
        ]
      }
    }
  }

  ndkVersion getExtOrDefault("ndkVersion")
  compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")

  buildFeatures {
    buildConfig true
    prefab true
  }

  defaultConfig {
    minSdkVersion getExtOrIntegerDefault("minSdkVersion")
    targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")

    externalNativeBuild {
      cmake {
        targets "node-api-host"
        cppFlags "-frtti -fexceptions -Wall -fstack-protector-all"
        arguments "-DANDROID_STL=c++_shared", "-Dweak-node-api_DIR=${findWeakNodeApiDir()}"
        abiFilters (*reactNativeArchitectures())

        buildTypes {
          debug {
            cppFlags "-O1 -g"
          }
          release {
            cppFlags "-O2"
          }
        }
      }
    }
  }

  externalNativeBuild {
    cmake {
      path "CMakeLists.txt"
    }
  }

  buildTypes {
    debug {
      jniDebuggable true
      packagingOptions {
        doNotStrip "**/*.so"
      }
    }
    release {
      minifyEnabled false
      externalNativeBuild {
        cmake {
          arguments "-DCMAKE_BUILD_TYPE=Release"
        }
      }
    }
  }

  lintOptions {
    disable "GradleCompatible"
  }

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

repositories {
  mavenCentral()
  google()
}

def kotlin_version = getExtOrDefault("kotlinVersion")

dependencies {
  implementation "com.facebook.react:react-android"
  implementation "com.facebook.react:hermes-engine"
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}

def commandLinePrefix = OperatingSystem.current().isWindows() ? ["cmd", "/c", "node"] : []
def cliPath = file("../bin/react-native-node-api.mjs")

// Custom task to fetch jniLibs paths via CLI
task linkNodeApiModules {
  doLast {
    exec {
      commandLine commandLinePrefix + [cliPath, 'link', '--android', rootProject.rootDir.absolutePath]
      standardOutput = System.out
      errorOutput = System.err
      // Enable color output
      environment "FORCE_COLOR", "1"
    }
    
    android.sourceSets.main.jniLibs.srcDirs += file("../auto-linked/android").listFiles()
  }
}

preBuild.dependsOn linkNodeApiModules

