import com.github.spotbugs.SpotBugsTask

import java.nio.file.Files

apply plugin: "com.android.application"
apply plugin: "com.github.spotbugs"
apply plugin: "pmd"
apply plugin: 'com.google.protobuf'

def ABORT_ON_CHECK_FAILURE = false

tasks.withType(Test) {
    systemProperty "MiFirmwareDir", System.getProperty("MiFirmwareDir", null)
    systemProperty "logback.configurationFile", System.getProperty("user.dir", null) + "/app/src/main/assets/logback.xml"
    systemProperty "GB_LOGFILES_DIR", Files.createTempDirectory("gblog").toString()
}
def getVersionCode = { ->
    try {
        def stdout = new ByteArrayOutputStream()
        exec {
            commandLine 'git', 'rev-list', 'HEAD', '--count'
            standardOutput = stdout
        }
        return Integer.valueOf(stdout.toString().trim())
    } catch (ignored) {
        return null
    }
}

def getGitHashShort = { ->
    try {
        def stdout = new ByteArrayOutputStream()
        exec {
            commandLine 'git', 'rev-parse', '--short', 'HEAD'
            standardOutput = stdout
        }
        return stdout.toString().trim()
    } catch (ignored){
        return null
    }
}

android {
    compileOptions {
        // for Android 5+
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    compileSdkVersion 29
    buildToolsVersion "31.0.0"

    defaultConfig {
        applicationId "nodomain.freeyourgadget.gadgetbridge"
        minSdkVersion 21
        targetSdkVersion 29

        // Note: always bump BOTH versionCode and versionName!
        versionName "0.71.2"
        versionCode 218
        vectorDrawables.useSupportLibrary = true
        buildConfigField "String", "GIT_HASH_SHORT", "\"${getGitHashShort()}\""
        buildConfigField "boolean", "INTERNET_ACCESS", "false"
        resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
        resValue "string", "app_name", "@string/application_name_generic"
        resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_generic"
        resValue "string", "about_activity_title", "@string/about_activity_title_generic"
        resValue "string", "about_description", "@string/about_description_generic"
        resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_generic"
    }
    signingConfigs {
        nightly {
            if (System.getProperty("nightly_store_file") != null) {
                storeFile file(System.getProperty("nightly_store_file"))
                storePassword System.getProperty("nightly_store_password")
                keyAlias System.getProperty("nightly_key_alias")
                keyPassword System.getProperty("nightly_key_password")
            }
        }
    }

    flavorDimensions "device_type"
    productFlavors {
        main {
            // Ensure that when starting from scratch, 'main' is selected, not 'banglejs'
            getIsDefault().set(true)
            // the default build product flavor
            dimension "device_type"
            //applicationIdSuffix ""
            //versionNameSuffix ""
        }
        banglejs {
            dimension "device_type"
            applicationId "com.espruino.gadgetbridge"
            applicationIdSuffix ".banglejs"
            versionNameSuffix "-banglejs"
            buildConfigField "boolean", "INTERNET_ACCESS", "true"
            // Disable pebble provider to allow Bangle.js Gadgetbridge to coexist with Gadgetbridge
            resValue "string", "pebble_content_provider", "com.getpebble.android.nopebble.bangle.provider"
            resValue "string", "app_name", "@string/application_name_banglejs_main"
            resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_banglejs_main"
            resValue "string", "about_activity_title", "@string/about_activity_title_banglejs_main"
            resValue "string", "about_description", "@string/about_description_banglejs_main"
            resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_banglejs_main"
            targetSdkVersion 30 // Bangle.js flavor only - We need SDK 30 for play store
            // Note: app/src/banglejs/AndroidManifest.xml contains some extra permissions we need to make SDK 30 work
        }
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
        }

        nightly {
            applicationIdSuffix ".nightly"
            versionNameSuffix "-${getGitHashShort}"
            minifyEnabled true
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
            resValue "string", "app_name", "@string/application_name_main_nightly"
            resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nightly"
            resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
            resValue "string", "about_description", "@string/about_description_main_nightly"
            resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
            
            debuggable true

            if (System.getProperty("nightly_store_file") != null) {
                signingConfig signingConfigs.nightly

                //this was conflicting with regular debug type (it should not), so it is only available for CI builds:
                productFlavors.main.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
                productFlavors.main.resValue "string", "app_name", "@string/application_name_main_nightly"
                productFlavors.main.resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nightly"
                productFlavors.main.resValue "string", "about_activity_title", "@string/about_activity_title_main_nightly"
                productFlavors.main.resValue "string", "about_description", "@string/about_description_main_nightly"
                productFlavors.main.resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nightly"
                
                //keep the pebble provider for people who want this. In case of need we can create Banglejs Nopebble
                productFlavors.banglejs.resValue "string", "pebble_content_provider", "com.getpebble.android.provider"
                productFlavors.banglejs.resValue "string", "app_name", "@string/application_name_banglejs_nightly"
                productFlavors.banglejs.resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_banglejs_nightly"
                productFlavors.banglejs.resValue "string", "about_activity_title", "@string/about_activity_title_banglejs_nightly"
                productFlavors.banglejs.resValue "string", "about_description", "@string/about_description_banglejs_nightly"
                productFlavors.banglejs.resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_banglejs_nightly"
            } else {
                signingConfig signingConfigs.debug
            }
        }
        nopebble {
            applicationIdSuffix ".nightly_nopebble"
            versionNameSuffix "-${getGitHashShort}"
            minifyEnabled true
            if (System.getProperty("nightly_store_file") != null) {
                signingConfig signingConfigs.nightly
            } else {
                signingConfig signingConfigs.debug
            }
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            resValue "string", "pebble_content_provider", "com.getpebble.android.nopebble.provider"
            resValue "string", "app_name", "@string/application_name_main_nopebble"
            resValue "string", "title_activity_controlcenter", "@string/title_activity_controlcenter_main_nopebble"
            resValue "string", "about_activity_title", "@string/about_activity_title_main_nopebble"
            resValue "string", "about_description", "@string/about_description_main_nopebble"
            resValue "string", "gadgetbridge_running", "@string/gadgetbridge_running_main_nopebble"
            debuggable true
        }

        applicationVariants.all { variant ->
            variant.resValue "string", "applicationId", variant.applicationId

            if (variant.buildType.name == 'nightly' || variant.buildType.name == 'nopebble') {
                variant.outputs.all {
                    setVersionCodeOverride(getVersionCode())
                    //setVersionNameOverride(getGitHashShort())
                    setVersionNameOverride(variant.versionName)
                    outputFileName = "${applicationId}_${variant.versionName}.apk"
                }
            }
        }

    }


    lintOptions {
        abortOnError ABORT_ON_CHECK_FAILURE
        lintConfig file("${project.rootDir}/config/lint/lint.xml")
// If true, generate an HTML report (with issue explanations, sourcecode, etc)
        htmlReport true
// Optional path to report (default will be lint-results.html in the builddir)
        htmlOutput file("$project.buildDir/reports/lint/lint.html")
    }

    testOptions {
        unitTests {
            returnDefaultValues = true
            includeAndroidResources = true
        }
    }
}

pmd {
    toolVersion = "5.5.5"
}

dependencies {
//    testImplementation "ch.qos.logback:logback-classic:1.1.3"
//    testImplementation "ch.qos.logback:logback-core:1.1.3"
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'
    testImplementation "junit:junit:4.13.2"
    testImplementation "org.mockito:mockito-core:1.10.19"
    testImplementation "org.robolectric:robolectric:4.8.2"
    testImplementation "org.hamcrest:hamcrest-library:1.3"
    testImplementation "com.google.code.gson:gson:2.8.6"

    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "androidx.appcompat:appcompat:1.3.1"
    implementation "androidx.preference:preference:1.1.1"
    implementation "androidx.cardview:cardview:1.0.0"
    implementation "androidx.recyclerview:recyclerview:1.2.1"
    implementation "androidx.legacy:legacy-support-v4:1.0.0"
    implementation "androidx.gridlayout:gridlayout:1.0.0"
    implementation "androidx.palette:palette:1.0.0"

    implementation "com.google.android.material:material:1.4.0"
    implementation 'com.google.android.flexbox:flexbox:3.0.0'
    implementation "com.google.code.gson:gson:2.8.6"

    implementation "no.nordicsemi.android:dfu:1.11.1"
    implementation("com.github.tony19:logback-android:2.0.0") {
        exclude group: "com.google.android", module: "android"
    }
    implementation "org.slf4j:slf4j-api:1.7.36"
    implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
    implementation "com.github.pfichtner:durationformatter:0.1.1"
    implementation "de.cketti.library.changelog:ckchangelog:1.2.2"
    implementation "net.e175.klaus:solarpositioning:0.0.9"
    implementation "co.nstant.in:cbor:0.9"
    // use pristine greendao instead of our custom version, since our custom jitpack-packaged
    // version contains way too much and our custom patches are in the generator only.
    implementation "org.greenrobot:greendao:2.2.1"
    implementation "org.apache.commons:commons-lang3:3.7"
    implementation "org.cyanogenmod:platform.sdk:6.0"
    implementation 'com.jaredrummler:colorpicker:1.0.2'
//    implementation project(":DaoCore")
    implementation 'com.github.wax911:android-emojify:0.1.7'
    implementation 'com.google.protobuf:protobuf-javalite:3.10.0'
    implementation 'com.android.volley:volley:1.2.1'

// NON-FOSS dependencies
//    implementation('androidx.core:core-google-shortcuts:1.0.1') {
//        exclude group:'com.google.android.gms'
//        exclude group:'com.google.firebase'
//    }

    // JSR-310 timezones backport for Android, since we're still API 21
    implementation 'com.jakewharton.threetenabp:threetenabp:1.4.0'
    testImplementation 'org.threeten:threetenbp:1.6.0'

    // Android SDK bundles org.json, but we need an actual implementation to replace the stubs in tests
    testImplementation 'org.json:json:20180813'
}

preBuild.dependsOn(":GBDaoGenerator:genSources")

gradle.beforeProject {
    preBuild.dependsOn(":GBDaoGenerator:genSources")
}

check.dependsOn "spotbugsMain", "pmd", "lint"

task pmd(type: Pmd) {
    ruleSetFiles = files("${project.rootDir}/config/pmd/pmd-ruleset.xml")
    ignoreFailures = !ABORT_ON_CHECK_FAILURE
    ruleSets = [
            "java-android",
            "java-basic",
            "java-braces",
            "java-clone",
            "java-codesize",
            "java-controversial",
            "java-coupling",
            "java-design",
            "java-empty",
            "java-finalizers",
            "java-imports",
            "java-junit",
            "java-optimizations",
            "java-strictexception",
            "java-strings",
            "java-sunsecure",
            "java-typeresolution",
            "java-unnecessary",
            "java-unusedcode"
    ]

    source "src"
    include "**/*.java"
    exclude "**/gen/**"

    reports {
        xml.enabled = false
        html.enabled = true
        xml {
            destination file("$project.buildDir/reports/pmd/pmd.xml")
        }
        html {
            destination file("$project.buildDir/reports/pmd/pmd.html")
        }
    }
}

// this is just for spotbugs to let the plugin create the task
sourceSets {
    main {
        main.java.srcDirs += "${protobuf.generatedFilesBaseDir}/main/javalite"
    }
}

spotbugs {
    toolVersion = "3.1.12"
    ignoreFailures = !ABORT_ON_CHECK_FAILURE
    effort = "default"
    reportLevel = "medium"
}

tasks.withType(SpotBugsTask) {
    source = fileTree('src/main/java')
    classes = files("${project.rootDir}/app/build/intermediates/javac/debug/classes")
    excludeFilter = new File("${project.rootDir}/config/findbugs/findbugs-filter.xml")
    reports {
        xml.enabled = false
        html.enabled = true
        xml {
            destination file ("$project.buildDir/reports/spotbugs/spotbugs-output.xml")
        }
        html {
            destination file ("$project.buildDir/reports/spotbugs/spotbugs-output.html")
        }
    }
}

task cleanGenerated(type: Delete) {
    delete fileTree('src/main/java/nodomain/freeyourgadget/gadgetbridge/proto') {
        include '**/*.java'
    }
    delete fileTree('src/main/java/nodomain/freeyourgadget/gadgetbridge/entities') {
        include '**/*.java'
        exclude '**/Abstract*.java'
    }
}

tasks.clean.dependsOn(tasks.cleanGenerated)

protobuf {
    protoc {
        artifact = 'com.google.protobuf:protoc:3.10.0'
    }
    generateProtoTasks {
        all().each { task ->
            task.builtins {
                java {
                    option 'lite'
                    // Uncomment this to get Android Studio to recognize the generated files
                    // this makes it think that all src files are generated though...
                    //outputSubDir = '../../../../../src/main/java/'
                }
            }
        }
    }
}