import java.util.regex.Matcher
import java.util.regex.Pattern

apply plugin: 'com.android.application'

android {
  compileSdkVersion 30
  ndkVersion "21.4.7075529"
  buildToolsVersion '30.0.3'

  compileOptions {
    targetCompatibility 1.8
    sourceCompatibility 1.8
  }

  defaultConfig {
    applicationId "se.leap.bitmaskclient"
    // the factor 1000 is used so that gplay users can upgrade from split apks ((current version number - 1) * 1000) + n
    // to extracted bundle apks, supplied by google
    versionCode 161 * 1000
    versionName "1.1.3"
    minSdkVersion 16
    targetSdkVersion 30
    vectorDrawables.useSupportLibrary = true
    buildConfigField 'boolean', 'openvpn3', 'false'


    //Build Config Fields for default donation details

    //This is the default donation URL and should be set to the donation page of LEAP
    // and this should not be set/altered anywhere else.
    buildConfigField 'String', 'default_donation_url', '"https://riseup.net/vpn/donate"'
    //The field to enable donations in the app.
    buildConfigField 'boolean', 'enable_donation', 'true'
    //The field to enable donation reminder popup in the app if enable_donation is set to 'false' this will be disabled.
    buildConfigField 'boolean', 'enable_donation_reminder', 'true'
    //The duration in days to trigger the donation reminder
    buildConfigField 'int', 'donation_reminder_duration', '7'
    //skip the account creation / login screen if the provider offers anonymous vpn usage, use directly the anonymous cert instead
    buildConfigField 'boolean', 'priotize_anonymous_usage', 'false'
    //allow manual gateway selection
    buildConfigField 'boolean', 'allow_manual_gateway_selection', 'true'
    // grey out background in EipFragment (main screen) if VPN is not running
    buildConfigField 'boolean', 'use_color_filter', 'true'

    // static update url pointing to the latest stable release apk
    buildConfigField "String", "update_apk_url", '"https://dl.bitmask.net/client/android/Bitmask-Android-latest.apk"'
    // the the pgp signature file of the apk
    buildConfigField "String", "signature_url", '"https://dl.bitmask.net/client/android/Bitmask-Android-latest.apk.sig"'
    // the version file contains the versionCode of the latest release
    buildConfigField "String", "version_file_url", '"https://dl.bitmask.net/client/android/versioncode.txt"'

    //ignore the following configs, only used in custom flavor
    buildConfigField 'String', 'donation_url', 'null'
    buildConfigField "String", "customProviderUrl", '""'
    buildConfigField "String", "customProviderIp", '""'
    buildConfigField "String", "customProviderApiIp", '""'
    buildConfigField "String", "geoipUrl", '""'

    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    dexOptions {
      jumboMode true
      multiDexEnabled true
    }

    ndk {
      abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
    }

    bundle {
      language {
        enableSplit = true
      }
      density {
        enableSplit = true
      }
      abi {
        enableSplit = true
      }
    }
  }

  flavorDimensions "branding", "implementation", "abi"
  productFlavors {
    productFlavors.all {
      ext.appName = null
      ext.splitApk = false
    }
    production {
      dimension "implementation"
    }
    insecure {
      dimension "implementation"
    }

    normal {
      dimension "branding"
      appName = "Bitmask"
      splitApk = true
    }

    custom {
      dimension "branding"

      //**************************************************************************
      //**************************************************************************
      //Configurations for custom branded app.

      //Change the package name as needed, e.g. "org.example.myapp"
      applicationId "se.leap.riseupvpn"
      //Set app name here
      appName = "Riseup VPN"
      //Provider base url, e.g. '"https://example.com"'
      def customProviderUrl = '"https://riseup.net"'
      buildConfigField "String", "customProviderUrl", customProviderUrl
      //static ip address of provider, using a commercially validated CA certificate to serve the provider.json
      def customProviderIp = '"198.252.153.70"'
      buildConfigField "String", "customProviderIp", customProviderIp
      //static ip address of the provider api, using a self signed certificate to serve provider.json, eip-service.json etc.
      def customProviderApiIp = '"198.252.153.107"'
      buildConfigField "String", "customProviderApiIp", customProviderApiIp
      def geoipUrl = '"https://api.black.riseup.net:9001/json"'
      buildConfigField "String", "geoipUrl", geoipUrl
      //Change the versionCode as needed
      //versionCode 1
      //Change the versionName as needed
      //versionName "0.9.9RC1"

      //skip the account creation / login screen if the provider offers anonymous vpn usage, use directly the anonymous cert instead
      buildConfigField 'boolean', 'priotize_anonymous_usage', 'true'
      //allow manual gateway selection
      buildConfigField 'boolean', 'allow_manual_gateway_selection', 'true'
      // grey out background in EipFragment (main screen) if VPN is not running
      buildConfigField 'boolean', 'use_color_filter', 'false'

      //Build Config Fields for automatic apk update checks

      // static update url pointing to the latest stable release apk
      def apkURL = '"https://dl.bitmask.net/RiseupVPN/android/RiseupVPN-Android-latest.apk"'
      buildConfigField "String", "update_apk_url", apkURL
      // the the pgp signature file of the apk
      def signatureURL = '"https://dl.bitmask.net/RiseupVPN/android/RiseupVPN-Android-latest.apk.sig"'
      buildConfigField "String", "signature_url", signatureURL
      // the version file should contain a single line with the versionCode of the latest release
      buildConfigField "String", "version_file_url", '"https://dl.bitmask.net/client/android/versioncode.txt"' //'"https://dl.bitmask.net/RiseupVPN/android/versioncode.txt"'

      //Build Config Fields for default donation details

      //This is the donation URL and should be set to the relevant donation page.
      buildConfigField 'String', 'donation_url', '"https://riseup.net/vpn/donate"'
      //The field to enable donations in the app.
      buildConfigField 'boolean', 'enable_donation', 'true'
      //The field to enable donation reminder popup in the app if enable_donation is set to 'false' this will be disabled.
      buildConfigField 'boolean', 'enable_donation_reminder', 'true'
      //The duration in days to trigger the donation reminder
      buildConfigField 'int', 'donation_reminder_duration', '7'

      // Build apks for each architecture, in addition to one 'fat' apk containing libraries for all all architectures
      // enable this if you're publishing in gplay
      ext {
        splitApk = true
      }

      //**************************************************************************
      //**************************************************************************

    }

    fatweb {
      dimension "abi"
      ext {
        abiVersionCode = 0
        abiFilter = "web"
      }
    }

    fat {
      dimension "abi"
      ext {
        abiVersionCode = 0
        abiFilter = ""
      }
    }

    x86 {
      dimension "abi"
      ndk {
        abiFilters "x86"
      }
      ext {
        abiVersionCode = 1
        abiFilter = "x86"
      }
    }

    armv7 {
      dimension "abi"
      ndk {
        abiFilters "armeabi-v7a"
      }
      ext {
        abiVersionCode = 2
        abiFilter = "armeabi-v7a"
      }
    }

    x86_64 {
      dimension "abi"
      ndk {
        abiFilters "x86_64"
      }
      ext {
        abiVersionCode = 3
        abiFilter = "x86_64"
      }
    }

    arm64 {
      dimension "abi"
      ndk {
        abiFilters "arm64-v8a"
      }
      ext {
        abiVersionCode = 4
        abiFilter = "arm64-v8a"
      }
    }
  }

  buildTypes {
    buildTypes.all {
      ext.appSuffix = ""
    }
    release {
      //runProguard true
      //ndk.debugSymbolLevel = "full"
      //minifyEnabled = true
      //shrinkResources true
      buildConfigField "Boolean", "DEBUG_MODE", "false"
    }
    beta {
      initWith release
      applicationIdSuffix ".beta"
      appSuffix = " Beta"
      buildConfigField "Boolean", "DEBUG_MODE", "true"

      // tor-android doesn't know this build-type, fallback to release in that case
      matchingFallbacks = ['release']
    }
    debug {
      testCoverageEnabled = true
      buildConfigField "Boolean", "DEBUG_MODE", "true"
    }
  }

  lintOptions {
    abortOnError false
  }

  sourceSets {
    main {
      assets.srcDirs = ['assets',
                        'ovpnlibs/assets',
                        '../ics-openvpn/main/build/ovpnassets',
                        // '../go/out' TODO: uncomment this line as soon as we want to use PT in production
                        ]
      jniLibs.srcDirs = ['../ics-openvpn/main/build/intermediates/cmake/skeletonRelease/obj/']
      jni.srcDirs = [] //disable automatic ndk-build

    }
    debug {
      assets.srcDirs = ['src/debug/assets',
                        /*'../go/out'*/]
    }

    test {
      resources.srcDirs += ['src/test/resources']
      java.srcDirs += ['src/sharedTest/java']
    }

    androidTest {
      java.srcDirs += ['src/sharedTest/java']
    }

    fatweb {
      java.srcDirs += ['src/fatweb/java']
    }

    fat {
      java.srcDirs += ['src/notFatweb/java']
    }

    x86 {
      java.srcDirs += ['src/notFatweb/java']
    }

    x86_64 {
      java.srcDirs += ['src/notFatweb/java']
    }

    armv7 {
      java.srcDirs += ['src/notFatweb/java']
    }

    arm64 {
      java.srcDirs += ['src/notFatweb/java']
    }

  }

  /**
   * BUILD VARAIANTS:
   * =================
   * Development builds:
   * --------------------
   * customProductionFatDebug -> branded development build, includes all ABIs
   * normalProductionFatDebug -> Bitmask development build, includes all ABIS
   * customProductionFatwebDebug -> branded development build, includes all ABIs, for distribution through a download page
   * normalProductionFatWebDebug ->  Bitmask development build, includes all ABIS, for distribution through a download page
   * customInsecureFatDebug -> branded development build, doesn't checks certificates (for test server setup w/o valid certificates), includes all ABIs
   * normalInsecureFatDebug -> Bitmask development build, doesn't checks certificates (for test server setup w/o valid certificates), includes all ABIs
   *
   * Branded Releases:
   * -----------------
   * customProductionFatBeta -> branded build, includes all ABI's, Beta release
   * customProductionFatRelease -> branded build, includes all ABI's, stable release (-> F-Droid, GPlay if not splitApk is set to true)
   * customProductionFatwebRelease -> branded build, includes all ABI's, stable release (-> F-Droid, GPlay if not splitApk is set to true), for distribution through a download page
   *
   * Bitmask Beta releases:
   * ----------------------
   * normalProductionArm64Beta  ->  Bitmask build, only for ABI arm64, for GPlay Beta channel with split apks (1 of 4)
   * normalProductionArmv7Beta  ->  Bitmask build, only for ABI armeabi-v7a, for GPlay Beta channel with split apks (2 of 4)
   * normalProductionX86Beta    ->  Bitmask build, only for ABI x86, for GPlay Beta channel with split apks (3 of 4)
   * normalProductionX86_64Beta ->  Bitmask build, only for ABI x86 64 bit, for GPlay Beta channel with split apks (4 of 4)
   * normalProductionFatBeta    ->  Bitmask build, including all ABIS, for izzysoft's F-Droid repo and beta link on download page
   *
   * Bitmask Stable releases:
   * ------------------------
   * normalProductionArm64Release  ->  Bitmask build, only for ABI arm64, for GPlay releases with split apks (1 of 4)
   * normalProductionArmv7Release  ->  Bitmask build, only for ABI armeabi-v7a, for GPlay releases with split apks (2 of 4)
   * normalProductionX86Release    ->  Bitmask build, only for ABI x86, for GPlay releases with split apks (3 of 4)
   * normalProductionX86_64Release ->  Bitmask build, only for ABI x86 64 bit, for GPlay releases with split apks (4 of 4)
   * normalProductionFatRelease    ->  Bitmask build, including all ABIS, for official F-Droid repo
   * normalProductionFatWebRelease ->  Bitmask build, including all ABIS, for distribution through a download page
   */

  variantFilter { variant ->

    def names = variant.flavors*.name
    def buildTypeName = variant.buildType.name
    // flavorDimensions "branding" -> 0, "implementation" -> 1, "abi" -> 2
    def supportsSplitApk = variant.flavors[0].splitApk
    // To check for a certain build type, use variant.buildType.name == "<buildType>"
    if (((names.contains("insecure") && !names.contains("fat")) ||
            (names.contains("insecure") && buildTypeName.contains("beta")) ||
            (names.contains("insecure") && buildTypeName.contains("release")) ||
            (buildTypeName.contains("debug") && !(names.contains("fatweb") || names.contains("fat"))) ||
            (names.contains("fatweb") && buildTypeName.contains("beta")) ||
            (!supportsSplitApk && !names.contains("fat")))
    ) {
      // Gradle ignores any variants that satisfy the conditions above.
      setIgnore(true)
    }
  }
}




dependencies {
  testImplementation 'junit:junit:4.12'
  //outdated mockito-core version due to powermock dependency
  testImplementation 'org.mockito:mockito-core:3.6.0'
  testImplementation('org.powermock:powermock-api-mockito2:2.0.9')
       //   { exclude group: 'junit' exclude group: 'org.mockito' }
  testImplementation 'org.powermock:powermock-module-junit4:2.0.9'
  testImplementation 'org.powermock:powermock-core:2.0.9'
  testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.9'
  testImplementation group: 'com.tngtech.java', name: 'junit-dataprovider', version: '1.10.0'

  androidTestImplementation 'org.mockito:mockito-core:3.6.0'
  androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
  androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'
  androidTestImplementation 'androidx.test.espresso:espresso-intents:3.4.0'
  //TODO: remove that library
  androidTestImplementation 'com.jayway.android.robotium:robotium-solo:5.6.3'
  testImplementation 'org.json:json:20180813'
  debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.2'
  releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2'
  betaImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2'
  annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
  annotationProcessor 'com.squareup.dagger:dagger-compiler:1.2.2'
  implementation 'com.jakewharton:butterknife:10.2.1'
  //TODO: replace that library
  compileOnly 'com.squareup.dagger:dagger-compiler:1.2.2'
  implementation 'com.github.pedrovgs:renderers:1.5'
  implementation 'com.google.code.gson:gson:2.8.6'
  implementation 'com.squareup.okhttp3:okhttp:3.12.12'
  implementation 'androidx.legacy:legacy-support-core-utils:1.0.0'
  implementation 'androidx.annotation:annotation:1.1.0'
  implementation 'androidx.legacy:legacy-support-v4:1.0.0'
  implementation 'androidx.appcompat:appcompat:1.2.0'
  implementation 'com.google.android.material:material:1.2.1'
  implementation 'androidx.fragment:fragment:1.2.5'
  implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
  implementation 'androidx.multidex:multidex:2.0.1'
  implementation 'androidx.cardview:cardview:1.0.0'
  implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
  implementation 'de.hdodenhof:circleimageview:3.1.0'


  //implementation 'info.guardianproject:tor-android:0.4.5.7'
  //implementation 'info.guardianproject:jtorctl:0.4.5.7'
  implementation project(path: ':tor-android:tor-android-binary')

  fatwebImplementation project(path: ':lib-bitmask-core-web')
  fatImplementation project(path: ':lib-bitmask-core')
  x86Implementation project(path: ':lib-bitmask-core-x86')
  x86_64Implementation project(path: ':lib-bitmask-core-x86_64')
  armv7Implementation project(path: ':lib-bitmask-core-armv7')
  arm64Implementation project(path: ':lib-bitmask-core-arm64')
}

android.applicationVariants.all { variant ->
  // configure app name and apk file name for different build variants
  def flavors = variant.productFlavors
  // flavorDimensions "branding" -> 0, "implementation" -> 1, "abi" -> 2
  def branding = flavors[0]
  def trimmedAppName = branding.appName.replaceAll(' ', '')
  def abiDimension = flavors[2]
  def abiFilter = abiDimension.abiFilter
  if (abiFilter.length() > 0) {
    abiFilter = "_"+abiFilter
  }
  def buildType = variant.buildType
  def tag = getTag()
  if (tag.length() > 0) {
    tag = "_"+tag
  }

  variant.resValue "string", "app_name",  "\"${branding.appName}${buildType.appSuffix}\""

  variant.outputs.all { output ->
    output.outputFileName = "${trimmedAppName}${abiFilter}_${buildType.name}${tag}.apk"
  }

  // reconfigure version codes for split builds
  variant.outputs.each { output ->
      // if not a fat build
      if (abiDimension.abiVersionCode > 0) {
          output.versionCodeOverride = android.defaultConfig.versionCode + abiDimension.abiVersionCode
      }
  }

  // remove unrelated abi specific assets
  variant.mergeAssetsProvider.get().doLast {
    // if not a fat build
    if (abiDimension.abiVersionCode > 0) {
      def filesToDelete = fileTree(dir: variant.mergeAssets.outputDir, excludes: ["*pie_openvpn.${abiDimension.abiFilter}",
                                                                                  'urls/',
                                                                                  '*.url',
                                                                                  '*.json',
                                                                                  '*.pem',
                                                                                  'fronts'])
      delete(filesToDelete)
    }
  }
}


// Ensure the no-op dependency is always used in JVM tests.
configurations.all { config ->
  if (config.name.contains('UnitTest')) {
    config.resolutionStrategy.eachDependency { details ->
      if (details.requested.group == 'com.squareup.leakcanary' && details.requested.name == 'leakcanary-android') {
        details.useTarget(group: details.requested.group, name: 'leakcanary-android-no-op', version: details.requested.version)
      }
    }
  }
}

subprojects {
  afterEvaluate {project ->
    if (project.hasProperty("android")) {
      android {
        compileSdkVersion 30
      }
    }
  }
}

task updateIcsOpenVpn( type: Exec ) {
  commandLine 'git', 'submodule', 'sync'
  commandLine 'git', 'submodule', 'update', '--init', '--recursive'
}

def getTag() {
  String commit = "git log --pretty=format:'%h' -n 1".execute().text.trim().replaceAll("'", "")
  return ("git describe --tags --exact-match "+ commit).execute().text.trim()
}

task cleanNative( type: Delete ) {
  def shouldClean = getCurrentFlavorForBetaOrRelease() == "production"
  println  "cleanNative: " + shouldClean

  if (shouldClean) {
    def dirName = "obj"
    file( dirName ).list().each{
      f -> delete "${dirName}/${f}"
    }
  }
}

task updateSdkLicences ( type: Exec ) {
  println "say yes to licenses"
  commandLine 'sh', 'yes', '|', 'sdkmanager', '--licenses'
}

def getCurrentFlavorForBetaOrRelease() {
  Gradle gradle = getGradle()
  String  tskReqStr = gradle.getStartParameter().getTaskRequests().toString()

  Pattern pattern;

  if( tskReqStr.contains( "assemble" ) )
    pattern = Pattern.compile("assemble(\\w+)(Beta|Release)")
  else
    pattern = Pattern.compile("generate(\\w+)(Beta|Release)")

  Matcher matcher = pattern.matcher( tskReqStr )

  if( matcher.find() )
    return matcher.group(1).toLowerCase()
  else
  {
    return "";
  }
}