import java.nio.file.Paths

def DEFAULT_KOTLIN_VERSION = "1.9.20"
def DEFAULT_ROOM_VERSION = "2.4.3"

def kotlinVersion = getKotlinVersion(DEFAULT_KOTLIN_VERSION)

project.ext.AsyncStorageConfig = [
        kotlinVersion           : kotlinVersion,
        kspVersion              : getKspVersion(kotlinVersion),
        roomVersion             : getPropertyOfDefault('AsyncStorage_next_roomVersion', DEFAULT_ROOM_VERSION),
        minSdkVersion           : safeExtGet('minSdkVersion', 23),
        targetSdkVersion        : safeExtGet('targetSdkVersion', 32),
        compileSdkVersion       : safeExtGet('compileSdkVersion', 32),
        useNextStorage          : getFlagOrDefault("AsyncStorage_useNextStorage", false),
        databaseSizeMB          : getDatabaseSize(),
        isNewArchitectureEnabled: isNewArchitectureEnabled(),
        useDedicatedExecutor    : getFlagOrDefault('AsyncStorage_dedicatedExecutor', false),
]

project.ext.AsyncStorageLibs = [
        coroutines     : "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3",
        testCoroutines : "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3",
        testJunit      : "junit:junit:4.13.2",
        testRunner     : "androidx.test:runner:1.4.0",
        testRules      : "androidx.test:rules:1.4.0",
        testExtJunit   : "androidx.test.ext:junit:1.1.3",
        testRobolectric: "org.robolectric:robolectric:4.11.1",
        testTruth      : "com.google.truth:truth:1.1.3",
]


def getKotlinVersion(String defaultVersion) {
    return rootProject.ext.has('kotlinVersion')
            ? rootProject.ext['kotlinVersion']
            : rootProject.hasProperty('AsyncStorage_kotlinVersion')
            ? rootProject.properties['AsyncStorage_kotlinVersion']
            : defaultVersion
}

def isNewArchitectureEnabled() {
    // To opt-in for the New Architecture, you can either:
    // - Set `newArchEnabled` to true inside the `gradle.properties` file
    // - Invoke gradle with `-newArchEnabled=true`
    // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
    return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
}

String getKspVersion(String kotlinVersion) {

    String overriddenKspVersion = getPropertyOfDefault("AsyncStorage_next_kspVersion", null)
    if (overriddenKspVersion != null) {
        return overriddenKspVersion
    }
    // https://github.com/google/ksp/releases
    def kspVersions = [
            "1.9.20-1.0.14",
            "1.9.10-1.0.13",
            "1.9.0-1.0.13",
            "1.8.22-1.0.11",
            "1.8.21-1.0.11",
            "1.8.20-1.0.11",
            "1.8.10-1.0.9",
            "1.8.0-1.0.9",
            "1.7.22-1.0.8",
            "1.7.21-1.0.8",
            "1.7.20-1.0.8",
            "1.7.10-1.0.6",
            "1.7.0-1.0.6",
            "1.6.21-1.0.6",
            "1.6.20-1.0.5",
            "1.6.10-1.0.4",
            "1.6.0-1.0.2",
            "1.5.31-1.0.1",
            "1.5.30-1.0.0",
    ]

    return kspVersions.find { it.startsWith(kotlinVersion) } ?: kspVersions.first()
}

// AsyncStorage has default size of 6MB.
// This is a sane limit to protect the user from the app storing too much data in the database.
// This also protects the database from filling up the disk cache and becoming malformed.
// If you really need bigger size, please keep in mind the potential consequences.
long getDatabaseSize() {
    long dbSizeInMB = 6L
    def newDbSize = getPropertyOfDefault('AsyncStorage_db_size_in_MB', null)
    if (newDbSize != null && newDbSize.isLong()) {
        dbSizeInMB = newDbSize.toLong()
    }
    return dbSizeInMB
}

def safeExtGet(prop, fallback) {
    rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
}

def getFlagOrDefault(flagName, defaultValue) {
    rootProject.hasProperty(flagName) ? rootProject.properties[flagName] == "true" : defaultValue
}

def getPropertyOfDefault(String flagName, String defaultVersion) {
    rootProject.hasProperty(flagName) ? rootProject.properties[flagName] : defaultVersion
}

ext.resolveModulePath = { packageName ->
    def basePath = rootDir.toPath().normalize()

    // Node's module resolution algorithm searches up to the root directory,
    // after which the base path will be null
    while (basePath) {
        def candidatePath = Paths.get(basePath.toString(), 'node_modules', packageName)
        if (candidatePath.toFile().exists()) {
            return candidatePath.toString()
        }

        basePath = basePath.getParent()
    }

    return null
}
