import java.nio.file.Paths

buildscript {

  repositories {
    google()
    mavenCentral()

    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath 'com.android.tools.build:gradle:4.2.1'
  }
}

apply plugin: 'com.android.library'

def getExtOrDefault(name, defaultValue) {
  return rootProject.ext.has(name) ? rootProject.ext.get(name) : defaultValue
}

static def findNodeModules(baseDir) {
  def basePath = baseDir.toPath().normalize()
  // Node's module resolution algorithm searches up to the root directory,
  // after which the base path will be null
  while (basePath) {
    def nodeModulesPath = Paths.get(basePath.toString(), "node_modules")
    def reactNativePath = Paths.get(nodeModulesPath.toString(), "react-native")
    if (nodeModulesPath.toFile().exists() && reactNativePath.toFile().exists()) {
      return nodeModulesPath.toString()
    }
    basePath = basePath.getParent()
  }
  throw new GradleException("MMKV: Failed to find node_modules/ path!")
}

def found = false
def basePath = projectDir.toPath().normalize()

// Find node_modules inside the example project
def nodeModulesDir = Paths.get(basePath.getParent().toString(), "example/node_modules")
def reactNativeDir = Paths.get(nodeModulesDir.toString(), "react-native/android")
def nodeModules = findNodeModules(projectDir)
def reactProperties = new Properties()
file("$nodeModules/react-native/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }
def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME").split("\\.")[1].toInteger()

if (nodeModulesDir.toFile().exists() && reactNativeDir.toFile().exists()) {
  found = true
}

if(!found){
  // Node's module resolution algorithm searches up to the root directory,
  // after which the base path will be null
  while (basePath) {
    nodeModulesDir = Paths.get(basePath.toString(), "node_modules")
    reactNativeDir = Paths.get(nodeModulesDir.toString(), "react-native/android")
    if (nodeModulesDir.toFile().exists() && reactNativeDir.toFile().exists()) {
      found = true
      break;
    }
    basePath = basePath.getParent()
  }
}

if(!found) {
    throw new GradleException(
            "${project.name}: unable to locate React Native android sources. " +
                    "Ensure you have you installed React Native as a dependency in your project and try again.")
}

def nodeModulesPath = nodeModulesDir.toString().replace("\\", "/")
def reactNativePath = reactNativeDir.toString().replace("\\", "/")


android {
  compileSdkVersion getExtOrDefault('compileSdkVersion', 28)

  defaultConfig {
    minSdkVersion getExtOrDefault('minSdkVersion', 16)
    targetSdkVersion getExtOrDefault('targetSdkVersion', 28)

    externalNativeBuild {
      cmake {
        cppFlags "-fexceptions", "-frtti", "-std=c++1y", "-DONANDROID"
        abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
        arguments '-DANDROID_STL=c++_shared', "-DNODE_MODULES_DIR=${nodeModulesPath}"
      }
    }
  }

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  lintOptions{
    abortOnError false
    disable 'GradleCompatible'
  }

  externalNativeBuild {
     cmake {
          path "./CMakeLists.txt"
      }
  }

  packagingOptions {
    excludes = ["**/libc++_shared.so","**/libjsi.so","**/libreactnativejni.so","META-INF/MANIFEST.MF"]
  }

  configurations {
    extractJNI
  }
}

repositories {
  mavenCentral()
  mavenLocal()
  google()

  maven {
    url reactNativePath
    name 'React Native sources'
  }
}

dependencies {
  //noinspection GradleDynamicVersion
  implementation 'com.facebook.react:react-native:+'
      def buildType = "debug"
    tasks.all({ task ->
      if (task.name == "buildCMakeRelease") {
        buildType = "release"
      }
    })
    def rnAarMatcher = "**/react-native/**/*${buildType}.aar"
if (REACT_NATIVE_VERSION < 69) {
      rnAarMatcher = "**/**/*.aar"
    }
  def rnAAR = fileTree(reactNativePath).matching({ it.include rnAarMatcher }).singleFile
  extractJNI(files(rnAAR))
}

def extracted = false;
task extractJNIFiles {
  if (extracted) return
  doLast {
    configurations.extractJNI.files.each {
      def file = it.absoluteFile

      copy {
        from zipTree(file)
        into "$buildDir/$file.name"
        include "jni/**/*"
      }
      extracted = true;
    }
  }
}

// Extract JNI files as soon as first task is added
tasks.whenTaskAdded { task ->
  task.dependsOn(extractJNIFiles);
}
