import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28

    defaultConfig {
        applicationId "net.named_data.nfd"
        minSdkVersion 23
        targetSdkVersion 23
        versionCode 4008
        versionName "0.6.2-1 (NFD 0.6.2-11-gd657d53)"
        multiDexEnabled true
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            debuggable true
            jniDebuggable true
        }
    }
    sourceSets {
        main {
            java.srcDirs "src/main/java"
            res.srcDirs "src/main/res"
            jniLibs.srcDir 'src/main/libs'
            jni.srcDirs = [] //disable automatic ndk-build call
        }
        androidTest.setRoot('tests')
        androidTest.java.srcDirs = ['tests/src']
    }
    packagingOptions {
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/NOTICE.txt'
    }
    lintOptions {
      abortOnError false
    }

    splits {
        abi {
            enable true // enable ABI split feature to create one APK per ABI
            reset()
            include "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
            universalApk false // don't generate an additional APK that targets all the ABIs
        }
    }

    // map for the version code
    // versionCode digit for each supported ABI, with 64bit>32bit and x86>armeabi-*
    project.ext.versionCodes = [//'armeabi': 1, // Deprecated in r16. Will be removed in r17. No hard float.
                                'armeabi-v7a': 2,
                                'arm64-v8a': 3,
                                // 'mips': 5,   // Deprecated in r16. Will be removed in r17. Uses hard-float, and assumes a CPU:FPU clock ratio of 2:1 for maximum compatibility. Provides neither micromips nor MIPS16.
                                // 'mips64': 6, // Deprecated in r16. WIll be removed in r17
                                'x86': 8,
                                'x86_64': 9]

    android.applicationVariants.all { variant ->
        // assign different version code for each output
        variant.outputs.each { output ->
            output.versionCodeOverride = project.ext.versionCodes.get(
                    output.getFilter(
                            com.android.build.OutputFile.ABI), 0) * 1000000 +
                    defaultConfig.versionCode
        }
    }

    task copyNdnCxxHeaders(type: Copy) {
        from('src/main/jni/ndn-cxx/src') {
            include '**/*.hpp'
        }
        into 'build/generated/source/include/ndn-cxx'
    }

    // call regular ndk-build(.cmd) script from app directory
    task ndkBuild(type: Exec) {
        dependsOn copyNdnCxxHeaders
        def args = [getNdkBuildCmd(), '-C', file('src/main').absolutePath]

        if (System.env.NDK_BUILD_PARALLEL != null) {
           args.add("-j" + System.env.NDK_BUILD_PARALLEL)
        }
        else {
           args.add("-j" + Runtime.runtime.availableProcessors())
        }

        if (System.env.NDK_BUILD_ABI != null) {
           args.add("APP_ABI=" + System.env.NDK_BUILD_ABI)
        }

        if (System.env.NDK_DEBUG != null) {
           args.add("V=1")
        }
        commandLine args
    }

    tasks.withType(JavaCompile) {
        compileTask -> compileTask.dependsOn ndkBuild
    }

    task cleanNative(type: Exec) {
        commandLine getNdkBuildCmd(), '-C', file('src/main').absolutePath, 'clean'
    }

    clean.dependsOn cleanNative
}

def getNdkBuildCmd() {
    def ndk_build = getNdkDir() + "/ndk-build"
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        ndk_build += ".cmd"
    }

    return ndk_build
}


def getNdkDir() {
    if (System.env.ANDROID_NDK_ROOT != null)
        return System.env.ANDROID_NDK_ROOT

    Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())

    def ndk_dir = properties.getProperty('ndk.dir', null)
    if (ndk_dir == null) {
        throw new GradleException("NDK location not found. Define location with ndk.dir in the local.properties file or with an ANDROID_NDK_ROOT environment variable.")
    }
    return ndk_dir
}

repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url "https://oss.sonatype.org/content/repositories/releases/"
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0-alpha3'
    implementation 'com.android.support:support-v4:28.0.0-alpha3'
    implementation 'com.android.volley:volley:1.1.1'

    implementation('net.named-data.jndn-extra:jndn-management:1.2.0') {
      exclude group: 'net.named-data', module: 'jndn'
    }
    implementation('net.named-data:jndn-android:0.17') {
      exclude group: 'org.xerial'
      exclude group: 'com.google.android'
    }
    implementation 'net.named-data.jndn-extra:jndn-xx-util:0.0.2'
    implementation 'joda-time:joda-time:2.10'
}

Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

if (properties['keystore'] == null || properties['keystore.password'] == null ||
    properties['keystore.key.alias'] == null || properties['keystore.key.password'] == null) {
    println("Cannot sign .apk: specify keystore, keystore.password, keystore.key.alias, and keystore.key.password in local.properties.")
}
else {
    android {
        signingConfigs {
            release {
                storeFile file(properties['keystore'])
                storePassword properties['keystore.password']
                keyAlias properties['keystore.key.alias']
                keyPassword properties['keystore.key.password']
            }
        }
        buildTypes {
            release {
                signingConfig signingConfigs.release
            }
        }
    }
}

if (properties['google-play'] != null) {
    // apply plugin: 'net.named-data.playground.play'
    apply plugin: 'com.github.triplet.play'

    play {
        track = 'alpha'
        jsonFile = file(properties['google-play'])
    }
}
