// Copyright (c) 2025-present, Punith M (punithm300@gmail.com)
// Enhanced PDF JSI Build Configuration with high-performance operations
// All rights reserved.

description = 'react-native-pdf'

buildscript {
    ext.safeExtGet = { prop, fallback ->
        rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
    }
    repositories {
        mavenCentral()
        google()
    }

    dependencies {
        classpath("com.android.tools.build:gradle:8.2.2")
    }
}

repositories {
    mavenCentral()
    maven {
        // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
        url "$projectDir/../node_modules/react-native/android"
        content {
            // Use Jitpack only for AndroidPdfViewer; the rest is hosted at mavenCentral.
            includeGroup "com.github.zacharee"
        }
    }
    maven { url 'https://jitpack.io' }
    google()
}

apply plugin: 'com.android.library'

def resolveReactNativeDirectory() {
    def reactNativeLocation = safeExtGet("REACT_NATIVE_NODE_MODULES_DIR", null)
    if (reactNativeLocation != null) {
        return file(reactNativeLocation)
    }

    // monorepo workaround
    // react-native can be hoisted or in project's own node_modules
    def reactNativeFromProjectNodeModules = file("${rootProject.projectDir}/../node_modules/react-native")
    if (reactNativeFromProjectNodeModules.exists()) {
        return reactNativeFromProjectNodeModules
    }

    def reactNativeFromNodeModulesWithPDF = file("${projectDir}/../../react-native")
    if (reactNativeFromNodeModulesWithPDF.exists()) {
        return reactNativeFromNodeModulesWithPDF
    }

    throw new Exception(
        "[react-native-pdf] Unable to resolve react-native location in " +
            "node_modules. You should add project extension property (in app/build.gradle) " +
            "`REACT_NATIVE_NODE_MODULES_DIR` with path to react-native."
    )
}

def getReactNativeMinorVersion() {
    def REACT_NATIVE_DIR = resolveReactNativeDirectory()

    def reactProperties = new Properties()
    file("$REACT_NATIVE_DIR/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) }

    def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME")
    def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.startsWith("0.0.0-") ? 1000 : REACT_NATIVE_VERSION.split("\\.")[1].toInteger()

    return REACT_NATIVE_MINOR_VERSION
}

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"
}

if (isNewArchitectureEnabled()) {
    apply plugin: "com.facebook.react"
}

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

android {
    def agpVersion = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION
    if (agpVersion.tokenize('.')[0].toInteger() >= 7) {
        namespace "org.wonday.pdf"
    }
    compileSdkVersion safeExtGet('compileSdkVersion', 35)
    
    // 🚀 NDK Configuration for 16KB Page Size Support
    // Use NDK r28.2 which provides proper 16KB page alignment toolchain
    ndkVersion "28.2.13676358"

    defaultConfig {
        minSdkVersion safeExtGet('minSdkVersion', 21)
        targetSdkVersion safeExtGet('targetSdkVersion', 35)
        buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString())
        
        // 🚀 JSI Configuration with 16KB Page Support
        ndk {
            abiFilters (*reactNativeArchitectures())
        }
        
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++17", "-fexceptions", "-frtti", "-O3", "-ffast-math", "-funroll-loops"
                arguments "-DANDROID_STL=c++_shared", "-DANDROID_PAGE_SIZE_AGNOSTIC=ON"
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            
            externalNativeBuild {
                cmake {
                    cppFlags "-DNDEBUG", "-O3", "-ffast-math", "-funroll-loops"
                }
            }
        }
        debug {
            debuggable true
            jniDebuggable true
            
            externalNativeBuild {
                cmake {
                    cppFlags "-DDEBUG", "-O0", "-g"
                }
            }
        }
    }
    
    // 🚀 JSI Native Build Configuration
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.22.1"
        }
    }

    sourceSets.main {
        java {
            if (!isNewArchitectureEnabled()) {
                srcDirs += [
                    "src/paper/java",
                ]
            }
            // 🚀 Add JSI Java sources
            srcDirs += ["src/main/java"]
        }
        jniLibs.srcDirs = ['src/main/jniLibs']
    }

    lintOptions {
        abortOnError true
    }

    packagingOptions {
        pickFirst 'lib/x86/libc++_shared.so'
        pickFirst 'lib/x86_64/libjsc.so'
        pickFirst 'lib/x86_64/libc++_shared.so'
        pickFirst 'lib/arm64-v8a/libjsc.so'
        pickFirst 'lib/arm64-v8a/libc++_shared.so'
        pickFirst 'lib/armeabi-v7a/libc++_shared.so'
        // 🚀 JSI Native Libraries
        pickFirst '**/libc++_shared.so'
        pickFirst '**/libjsc.so'
    }
    
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    if (isNewArchitectureEnabled() && getReactNativeMinorVersion() < 71) {
        implementation project(":ReactAndroid")
    } else {
        implementation 'com.facebook.react:react-native:+'
    }
    // NOTE: The original repo at com.github.barteksc is abandoned by the maintainer; there will be no more updates coming from that repo.
    // The repo from zacharee is based on PdfiumAndroidKt, a much newer fork of PdfiumAndroid, with better maintenance and updated native libraries.
    // Keep viewer at a Java 17-compatible version; exclude bundled PdfiumAndroid
    implementation('com.github.zacharee:AndroidPdfViewer:4.0.1') {
        exclude group: 'com.github.barteksc', module: 'PdfiumAndroid'
    }
    // Depend on PdfiumAndroidKt directly so this can be updated independently of AndroidPdfViewer as updates are provided.
    implementation 'io.legere:pdfiumandroid:1.0.32'
    implementation 'com.google.code.gson:gson:2.11.0'
    
    // 🚀 Android dependencies for JSI
    implementation 'androidx.annotation:annotation:1.7.0'
    implementation 'androidx.core:core:1.12.0'
}