import groovy.io.FileType

import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: 'ThemerConstants.gradle'

ext {
    // Encryption values, do not touch as we generate a random key every time you compile!
    byte[] key = new byte[16]
    new Random().nextBytes(key)
    KEY = key
    byte[] iv = new byte[16]
    new Random().nextBytes(iv)
    IV_KEY = iv
}

android {
    compileSdkVersion 28

    defaultConfig {
        // If you're planning to change up the package name, ensure you have read the readme
        // thoroughly!
        applicationId "it.folgore95.pixel"
        // We are only supporting Nougat and above, all new changes will incorporate Nougat changes
        // to the substratum repo rather than anything lower. Keep targetSdkVersion the same.
        minSdkVersion 24
        targetSdkVersion 28
        // Both versions must be changed to increment on Play Store/user's devices
        versionCode 273
        versionName "7.1"

        // Themers: Do not touch this, they will only formulate integrity structure of the core
        //          template
        buildConfigField "boolean", "SUPPORTS_THIRD_PARTY_SYSTEMS", "" + SUPPORTS_THIRD_PARTY_SYSTEMS
        buildConfigField "String", "BASE_64_LICENSE_KEY", "\"" + BASE_64_LICENSE_KEY + "\""
        buildConfigField "String", "APK_SIGNATURE_PRODUCTION", "\"" + APK_SIGNATURE_PRODUCTION + "\""
        buildConfigField "boolean", "ENABLE_APP_BLACKLIST_CHECK", "" + ENABLE_APP_BLACKLIST_CHECK
        buildConfigField "boolean", "ENFORCE_INTERNET_CHECK", "" + ENFORCE_INTERNET_CHECK
        buildConfigField "boolean", "ENFORCE_GOOGLE_PLAY_INSTALL", "" + ENFORCE_GOOGLE_PLAY_INSTALL
        buildConfigField "boolean", "ENFORCE_AMAZON_APP_STORE_INSTALL", "" + ENFORCE_AMAZON_APP_STORE_INSTALL
        buildConfigField "boolean", "ALLOW_THIRD_PARTY_SUBSTRATUM_BUILDS", "" + ALLOW_THIRD_PARTY_SUBSTRATUM_BUILDS
        resValue "string", "encryption_status", (shouldEncrypt() ? "onCompileVerify" : "false")

        buildConfigField "String", "IV_KEY", "\"" + IV_KEY + "\""
        buildConfigField "byte[]", "DECRYPTION_KEY", String.valueOf("\"" + KEY + "\"").replace("\"", "").replace("[", "{").replace("]", "}")
        buildConfigField "byte[]", "IV_KEY", String.valueOf("\"" + IV_KEY + "\"").replace("\"", "").replace("[", "{").replace("]", "}")
    }
    buildTypes {
        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        release {
            // When you compile an APK as release, your resources and IV keys will be safeguarded
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.github.javiersantos:PiracyChecker:1.2.3'
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version") {
        transitive = true
    }
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha03'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
    implementation 'com.google.android.material:material:1.1.0-alpha05'
}

// Themers, do not touch this! This is our function to help us encrypt your assets!
task encryptAssets {
    if (!shouldEncrypt()) {
        println("Skipping assets encryption...")
        return
    }

    def tempAssets = new File(getProjectDir(), "/src/main/assets-temp")
    if (!tempAssets.exists()) {
        println("Encrypting duplicated assets, don't worry, your original assets are safe...")
        def list = []
        def dir = new File(getProjectDir(), "/src/main/assets")
        dir.eachFileRecurse(FileType.FILES) { file ->
            list << file

            FileInputStream fis = new FileInputStream(file)
            File fo = new File(file.getAbsolutePath().replace("assets", "assets-temp"))
            fo.getParentFile().mkdirs()
            FileOutputStream fos = new FileOutputStream(fo)
            byte[] buffer = new byte[4096]
            int n
            while ((n = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, n)
            }
            fis.close()
            fos.close()
        }

        list.each {
            if (it.getAbsolutePath().contains("overlays")) {
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
                SecretKey secret = new SecretKeySpec(KEY, "AES")
                IvParameterSpec iv = new IvParameterSpec(IV_KEY)

                cipher.init(Cipher.ENCRYPT_MODE, secret, iv)
                FileInputStream fis = new FileInputStream(it)
                FileOutputStream fos = new FileOutputStream(it.getAbsolutePath() + ".enc")

                byte[] input = new byte[64]
                int bytesRead
                while ((bytesRead = fis.read(input)) != -1) {
                    byte[] output = cipher.update(input, 0, bytesRead)
                    if (output != null) {
                        fos.write(output)
                    }
                }
                byte[] output = cipher.doFinal()
                if (output != null) {
                    fos.write(output)
                }
                fis.close()
                fos.flush()
                fos.close()

                it.delete()
            }
        }
    } else {
        throw new RuntimeException("Old temporary assets found! Try and do a clean project.")
    }
}

project.afterEvaluate {
    preBuild.dependsOn encryptAssets
}

gradle.buildFinished {
    def tempAssets = new File(getProjectDir(), "/src/main/assets-temp")
    if (tempAssets.exists()) {
        println("Cleaning duplicated encrypted assets, not your decrypted assets...")
        def encryptedAssets = new File(getProjectDir(), "src/main/assets")
        encryptedAssets.deleteDir()

        tempAssets.eachFileRecurse(FileType.FILES) { file ->
            FileInputStream fis = new FileInputStream(file)
            File fo = new File(file.getAbsolutePath().replace("assets-temp", "assets"))
            fo.getParentFile().mkdirs()
            FileOutputStream fos = new FileOutputStream(fo)
            byte[] buffer = new byte[4096]
            int n
            while ((n = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, n)
            }
            fis.close()
            fos.close()
        }
        tempAssets.deleteDir()
    }
}

boolean shouldEncrypt() {
    ArrayList<String> tasks = project.gradle.startParameter.taskNames
    return SHOULD_ENCRYPT_ASSETS && Arrays.toString(tasks).toLowerCase().contains("release")
}

repositories {
    mavenCentral()
}
