import groovy.json.JsonSlurper
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes

String getPackageJsonPath() {
    // If APPSFLYER_PACKAGE_JSON_PATH property is set by the developer, use it.
    String envPath = findProperty("APPSFLYER_PACKAGE_JSON_PATH") as String
    if (envPath) {
        logger.lifecycle("package.json path from APPSFLYER_PACKAGE_JSON_PATH: $envPath")
        return envPath
    }

    // Potential relative paths to the package.json.
    def possiblePackageJsonPaths = [
            "${projectDir.parentFile}/package.json",
            "${buildDir.parentFile.parentFile}/package.json",
            "${rootDir.parentFile}/node_modules/appsflyer-capacitor-plugin/package.json",
    ]

    // Loop through the possible paths and find the first one that exists
    for (possiblePath in possiblePackageJsonPaths) {
        File possibleFile = file(possiblePath)
        if (possibleFile.exists()) {
            logger.lifecycle("Found package.json at: ${possibleFile.absolutePath}")
            return possibleFile.absolutePath
        }
    }

    logger.lifecycle("Did not locate package.json in any of possiblePackageJsonPaths and APPSFLYER_PACKAGE_JSON_PATH is not specified.")
    return null
}

/**
 * Finds the node_modules directory by traversing up the directory hierarchy starting from the given directory.
 *
 * @param currentDir The directory from which to start the search.
 * @return The discovered node_modules directory, or null if not found.
 */
static def findNodeModulesDir(File currentDir) {
    def dir = currentDir
    while (dir != null) {
        def nodeModulesDir = new File(dir, 'node_modules')
        if (nodeModulesDir.exists()) {
            return nodeModulesDir
        }
        dir = dir.parentFile
    }
    return null
}

/**
 * Searches for a package.json file corresponding to the given package name within the node_modules directory.
 *
 * The search begins from the root project directory and recursively checks each node_modules folder found
 * in parent directories up until the root of the file system hierarchy.
 *
 * @param packageName The name of the package for which to find package.json.
 * @return The contents of the package.json as a Map, or null if not found.
 */
def findPackageJsonInDep(String packageName) {
    // Start the search from the root project directory
    def nodeModulesDir = findNodeModulesDir(project.rootDir)
    if (nodeModulesDir == null) {
        logger.lifecycle("node_modules directory not found in any parent directories.")
        return null
    }

    def json = null

    def walker = new SimpleFileVisitor<Path>() {
        @Override
        FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
            // Looking specifically for the package.json of the target package
            if (file.toAbsolutePath().endsWith("appsflyer-capacitor-plugin/package.json")) {
                try {
                    def content = new JsonSlurper().parseText(file.toFile().text)
                    if (content.name == packageName) {
                        logger.lifecycle("Found package.json at: ${file.toAbsolutePath()}")
                        json = content
                        return FileVisitResult.TERMINATE
                    }
                } catch (Exception e) {
                    logger.lifecycle("Error parsing JSON in file: ${file.toAbsolutePath().toString()}\n${e.message}\n\t")
                }
            }
            return FileVisitResult.CONTINUE
        }
    }
    // Recursively walk through the file system starting from the node_modules directory
    while (json == null && nodeModulesDir != null) {
        Files.walkFileTree(nodeModulesDir.toPath(), walker)
        // Search for another node_modules directory two levels up
        nodeModulesDir = findNodeModulesDir(nodeModulesDir.parentFile.parentFile)
    }
    return json
}

def getPackageJson() {
    // Use the safe navigation operator when working with possible null values
    String packageJsonPath = getPackageJsonPath()
    File inputFile = packageJsonPath ? new File(packageJsonPath) : null

    // Attempt to load the package.json if the path is found and the file exists
    if (inputFile?.exists()) {
        try {
            return new JsonSlurper().parseText(inputFile.getText('UTF-8'))
        } catch (Exception e) {
            logger.error("Failed to parse package.json at: ${inputFile.absolutePath}", e)
        }
    } else {
        // package.json not found; search recursively
        logger.lifecycle("Searching for package.json recursively in node_modules directories...")
        def foundJson = findPackageJsonInDep("appsflyer-capacitor-plugin")
        if (foundJson) {
            return foundJson
        }
    }
    // If we got here the package.json was not loaded, log an error and return null
    logger.error("The plugin package.json could not be loaded properly; appsflyer-capacitor-plugin may not function as expected.")
    return null
}

ext {
    // Initialize only once and reuse it for all subsequent calls
    packageJson = getPackageJson()

    junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
    androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
    androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
    androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
    af_sdk_version = packageJson?.androidSdkVersion
    plugin_version = packageJson?.version
    plugin_build_version = packageJson?.buildNumber
}

buildscript {
    ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '2.2.20'
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:8.13.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'org.codehaus.groovy:groovy-json:3.0.9'
    }
}

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

android {
    namespace = "capacitor.plugin.appsflyer.sdk"
    compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
    defaultConfig {
        minSdkVersion = project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
        targetSdkVersion = project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
        versionCode = Integer.parseInt(plugin_build_version)
        versionName = "$plugin_version"
        buildConfigField "int", "VERSION_CODE", plugin_build_version
        buildConfigField "String", "VERSION_NAME", "\"$plugin_version\""
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled = false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    lint {
        abortOnError = false
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_21
        targetCompatibility JavaVersion.VERSION_21
    }
    buildFeatures {
        buildConfig = true
    }
}

kotlin {
    compilerOptions {
        jvmTarget = JvmTarget.JVM_21
    }
}

repositories {
    google()
    mavenCentral()
}


dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation project(':capacitor-android')
    implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
    testImplementation "junit:junit:$junitVersion"
    androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
    androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
    implementation "androidx.core:core-ktx:1.8.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

    implementation "com.appsflyer:af-android-sdk:$af_sdk_version"
    implementation "com.android.installreferrer:installreferrer:2.2"


}
