apply plugin: 'com.android.library'

// buildhost settings - paths and the like
apply from: 'libSettings.gradle'

layout.buildDirectory.set(rootProject.layout.buildDirectory.dir("lib"))

android {
    namespace 'org.libreoffice.androidlib'
    compileSdk 36
    buildToolsVersion "36.0.0"
    ndkVersion "29.0.14206865"
    buildFeatures.buildConfig = true

    defaultConfig {
        minSdk 26
        targetSdk 35
        versionCode 1
        versionName "1.0"

        resValue "string", "app_name", "${liboAppName}"
        buildConfigField "String", "GIT_COMMIT", "\"${liboOVersionHash}\""
        buildConfigField "boolean", "GOOGLE_PLAY_ENABLED", "${liboGooglePlay}"

        externalNativeBuild {
            cmake {
                arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_STL=c++_shared"
            }
        }
    }

    splits {
        abi {
            enable true

            reset ()
            for (abi in liboAbiSplit) {
                //noinspection ChromeOsAbiSupport - we generate liboAbiSplit at configure time, so we won't include ChromeOS support if we're not trying to build for it...
                include(abi)
            }
        }
    }

    lint {
        disable 'MissingTranslation', 'ExtraTranslation'
    }

    buildTypes {
        debug {
            resValue "string", "app_name", "${liboAppName} Debug"
            debuggable true
        }
        release {
            minifyEnabled false // FIXME disabled before we get a good proguardRules for callFakeWebsocketOnMessage calling from C++
            shrinkResources false // FIXME cannot be enabled when minifyEnabled is turned off
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    sourceSets {
        main {
            // let gradle pack the shared library into apk
            jniLibs.srcDirs = ['src/main/cpp/lib']
        }
    }

    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            buildStagingDirectory "${rootProject.layout.buildDirectory.get()}/cmake"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.7.1'
    implementation 'com.google.android.material:material:1.13.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.2.1'

    // https://stackoverflow.com/questions/75263047/duplicate-class-in-kotlin-android
    constraints {
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
            because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
        }
        implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
            because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
        }
    }
}

tasks.register('copyUnpackAssets', Copy) {
    description "copies assets that need to be extracted on the device"
    into 'src/main/assets/unpack'
    into('program') {
        from("${liboInstdir}/program/types") {
            includes = [
                    "offapi.rdb",
                    "oovbaapi.rdb"
            ]
        }
        from("${liboInstdir}/program") {
            includes = ["types.rdb"]
            rename 'types.rdb', 'udkapi.rdb'
        }

        into('resource') {
            from "${liboInstdir}/program/resource"
            includes = ['**']
        }
    }
    into('etc/coolwsd') {
        from('/android/coolkitconfig.xcu')
        includes = ['coolkitconfig.xcu']
    }
    into('user/fonts') {
        from "${liboInstdir}/share/fonts/truetype"
        // Note: restrict list of fonts due to size considerations - no technical reason anymore
        // ToDo: fonts would be good candidate for using Expansion Files instead
        includes = [
                "EmojiOne*.ttf",
                "Liberation*.ttf",
                "Caladea-*.ttf",
                "Carlito-*.ttf",
                "Gen*.ttf",
                "opens___.ttf"
        ]
    }
    into('etc/fonts') {
        from "${liboSrcRoot}/android/source/"
        includes = ['fonts.conf']
        doFirst {
            // we have changed the filter below; so to always re-generate this
            // file, delete it first - no idea how to set a dependency on
            // build.gradle changes :-(
            file('fonts.conf').delete()
        }
        filter {
            String line ->
                line.replaceAll(
                        '@@APPLICATION_ID@@', new String("${liboApplicationId}")
                )
        }
    }
    into('share') {
        from "${liboInstdir}/share"
        // liblangtag data is needed for locales like en-CH
        include 'liblangtag/**'
    }

    into('share') {
        from "${liboInstdir}/share"
        // extensions - for the dictionaries for hunspell
        includes = ['extensions/dict-de/**', 'extensions/dict-en/**', 'extensions/dict-es/**', 'extensions/dict-fr/**', 'extensions/dict-pt-BR/**']
        exclude { FileTreeElement details ->
            !(details.file.isDirectory() ||
                    details.file.name.endsWith('.xcu') ||
                    details.file.name.endsWith('.dic') ||
                    details.file.name.endsWith('.aff') ||
                    details.file.name.endsWith('.xml'))
        }
    }
}

tasks.register('copyAssets', Copy) {
    description "copies assets that can be accessed within the installed apk"
    into 'src/main/assets'
    from("${liboSrcRoot}/instdir/") {
        includes = ["LICENSE.html", "NOTICE"]
        rename "LICENSE.html", "license.html"
        rename "NOTICE", "notice.txt"
    }
    from("${liboExampleDocument}") {
        rename ".*", "example.odt"
    }
    into('program') {
        from "${liboInstdir}/program"
        includes = ['services.rdb', 'services/services.rdb']
    }
    into('share') {
        from "${liboInstdir}/share"
        // Filter data is needed by e.g. the drawingML preset shape import.
        includes = ['registry/**', 'filter/**', 'gallery/**', 'palette/**']
    }
}

tasks.register('createFullConfig', Copy) {
    description "copies various configuration bits into the apk"
    into('src/main/assets/share/config')
    from("${liboInstdir}/share/config") {
        includes = ['soffice.cfg/**', 'images_colibre.zip']
    }
}

tasks.register('copyBrandTheme', Copy) {
    from "${liboBrandingDir}/online-theme"
    into "src/main/assets/share/theme_definitions/online"
}

tasks.register('copyDocTemplates', Copy) {
    from "${rootProject.getRootDir()}/templates/untitled.odp",
            "${rootProject.getRootDir()}/templates/untitled.ods",
            "${rootProject.getRootDir()}/templates/untitled.odt"
    into "src/main/assets/templates"
}

tasks.register('copyKitConfig', Copy) {
    from "${file(rootProject.getRootDir()).getParent()}/coolkitconfig-mobile.xcu"
    into "src/main/assets/etc/coolwsd"
    rename { "coolkitconfig.xcu" }
}

tasks.register('createStrippedConfig') {
    def preserveDir = file("src/main/assets/share/config/soffice.cfg/empty")
    outputs.dir "src/main/assets/share/registry/res"
    outputs.file preserveDir

    doLast {
        file('src/main/assets/share/registry/res').mkdirs()
        file("src/main/assets/share/config/soffice.cfg").mkdirs()
        // just empty file
        preserveDir.text = ""
    }
}

tasks.register('createRCfiles') {
    inputs.file "libSettings.gradle"
    dependsOn copyUnpackAssets, copyAssets
    def sofficerc = file('src/main/assets/unpack/program/sofficerc')
    def fundamentalrc = file('src/main/assets/program/fundamentalrc')
    def bootstraprc = file('src/main/assets/program/bootstraprc')
    def unorc = file('src/main/assets/program/unorc')
    def lounorc = file('src/main/assets/program/lounorc')
    def versionrc = file('src/main/assets/program/versionrc')

    outputs.files sofficerc, fundamentalrc, unorc, bootstraprc, versionrc

    doLast {
        sofficerc.text = '''\
[Bootstrap]
Logo=1
NativeProgress=1
URE_BOOTSTRAP=file:///assets/program/fundamentalrc
HOME=$APP_DATA_DIR/cache
OSL_SOCKET_PATH=$APP_DATA_DIR/cache
'''.stripIndent()

        fundamentalrc.text = '''\
[Bootstrap]
LO_LIB_DIR=file://$APP_DATA_DIR/lib/
BRAND_BASE_DIR=file:///assets
BRAND_SHARE_SUBDIR=share
URE_BIN_DIR=file:///assets/ure/bin/dir/nothing-here/we-can/exec-anyway
BAK_EXTENSIONS=${$ORIGIN/lounorc:TMP_EXTENSIONS}
BUNDLED_EXTENSIONS=${$ORIGIN/lounorc:BUNDLED_EXTENSIONS}
BUNDLED_EXTENSIONS_USER=${$ORIGIN/lounorc:BUNDLED_EXTENSIONS_USER}
SHARED_EXTENSIONS_USER=${$ORIGIN/lounorc:SHARED_EXTENSIONS_USER}
UNO_SHARED_PACKAGES_CACHE=${$ORIGIN/lounorc:UNO_SHARED_PACKAGES_CACHE}
TMP_EXTENSIONS=${$ORIGIN/lounorc:TMP_EXTENSIONS}
UNO_USER_PACKAGES_CACHE=${$ORIGIN/lounorc:UNO_USER_PACKAGES_CACHE}
'''.stripIndent()

        bootstraprc.text = '''\
[Bootstrap]
InstallMode=<installmode>
ProductKey=LibreOffice ''' + "${liboVersionMajor}.${liboVersionMinor}" + '''
UserInstallation=file://$APP_DATA_DIR
'''.stripIndent()

        unorc.text = '''\
[Bootstrap]
URE_INTERNAL_LIB_DIR=file://$APP_DATA_DIR/lib/
UNO_TYPES=file://$APP_DATA_DIR/program/udkapi.rdb file://$APP_DATA_DIR/program/offapi.rdb file://$APP_DATA_DIR/program/oovbaapi.rdb
UNO_SERVICES=file:///assets/program/services.rdb file:///assets/program/services/services.rdb
'''.stripIndent()

        lounorc.text = '''\
[Bootstrap]
PKG_BundledUnoFile=$BUNDLED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
PKG_SharedUnoFile=$SHARED_EXTENSIONS_USER/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
PKG_UserUnoFile=$UNO_USER_PACKAGES_CACHE/registry/com.sun.star.comp.deployment.component.PackageRegistryBackend/unorc
BAK_EXTENSIONS=${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}/user/extensions/bak
BUNDLED_EXTENSIONS=${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}/share/extensions
BUNDLED_EXTENSIONS_USER=${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}/user/extensions/bundled
TMP_EXTENSIONS=${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}/user/extensions/tmp
SHARED_EXTENSIONS_USER=${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}/user/extensions/shared
UNO_SHARED_PACKAGES=${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}/share/uno_packages
UNO_SHARED_PACKAGES_CACHE=$UNO_SHARED_PACKAGES/cache
UNO_USER_PACKAGES=${$BRAND_BASE_DIR/program/bootstraprc:UserInstallation}/user/uno_packages
UNO_USER_PACKAGES_CACHE=$UNO_USER_PACKAGES/cache
'''.stripIndent()

        versionrc.text = '''\
[Version]
AllLanguages=en-US
BuildVersion=
buildid=''' + "${liboCoreVersionHash}" + '''
ReferenceOOoMajorMinor=4.1
'''.stripIndent()
    }
}

clean.doFirst {
	delete "src/main/assets"
	delete "src/debug/assets"
	delete "src/release/assets"
}

// creating the UI stuff is cheap, don't bother only applying it for the flavor..
preBuild.dependsOn 'createRCfiles',
        'createFullConfig',
        'copyBrandTheme'

tasks.register('generateCoolDebugAssets') {
    doLast {
        providers.exec {
            commandLine 'make', '-C', "${rootProject.layout.buildDirectory.get()}/../../browser", 'clean'
        }.result.get()
        providers.exec {
            commandLine 'make', '-C', "${rootProject.layout.buildDirectory.get()}/../../browser", "DIST_FOLDER=${project.layout.projectDirectory}/src/debug/assets/dist", 'BUNDLE=DEBUG'
        }.result.get()
    }
}

tasks.register('generateCoolReleaseAssets') {
    doLast {
        providers.exec {
            commandLine 'make', '-C', "${rootProject.layout.buildDirectory.get()}/../../browser", 'clean'
        }.result.get()
        providers.exec {
            commandLine 'make', '-C', "${rootProject.layout.buildDirectory.get()}/../../browser", "DIST_FOLDER=${project.layout.projectDirectory}/src/release/assets/dist", 'BUNDLE=RELEASE'
        }.result.get()
    }
}

afterEvaluate {
	if (!file("${liboBrandingDir}").exists()) {
		copyBrandTheme.enabled = false
	}
	generateDebugAssets.dependsOn copyDocTemplates, copyKitConfig, generateCoolDebugAssets
	generateReleaseAssets.dependsOn copyDocTemplates, copyKitConfig, generateCoolReleaseAssets

    // These tasks only exist under some cases (not in Android Studio)...
    // ...so use tasks.named so they don't fail if they are never registered...
    // ...also allows us to do the same thing for lots of tasks which are in the same case after the latest Android Gradle Plugin upgrade...
    tasks.named { it in [
        "generateDebugLintModel",
        "generateDebugLintReportModel",
        "generateDebugLintVitalModel",
        "generateReleaseLintModel",
        "generateReleaseLintVitalModel",
        "lintAnalyzeDebug",
        "lintVitalAnalyzeRelease",
    ] }.configureEach {
        dependsOn copyDocTemplates, copyKitConfig
    }
}
