// generate proguard config for log
class LogProguardRuleTask extends DefaultTask {

    @Input
    String projectName

    @Input
    String[] proguardClassList

    @Input
    String currentLogLevel

    @OutputFile
    File logProguardFile

    private ArrayList<String> removeLogLevels
    private HashMap<String, String> allowedLogLevels

    LogProguardRuleTask() {
        removeLogLevels = new ArrayList<>()
        allowedLogLevels = [VERBOSE: "v",
                            DEBUG  : "d",
                            INFO   : "i",
                            WARN   : "w",
                            ERROR  : "e"]
    }

    private void updateProguardFile() {
        File file = logProguardFile
        if (file.exists()) {
            file.delete()
        }

        file.createNewFile()
        file.append("\n" + genProguardRules())
    }

    private String genProguardRules() {
        def rules = ""
        for (String logClass : proguardClassList) {
            def rule = genLogRules(logClass, removeLogLevels)
            logger.lifecycle(rule)
            rules += rule
        }
        return rules
    }

    private String genLogRules(clazz, levels) {
        def sb = new StringBuilder()
        sb.append(String.format("-assumenosideeffects class %s{\n", clazz))
        for (String level : levels) {
            sb.append(String.format("   public static *** %s(...);\n", level))
        }
        sb.append("}\n")
        return sb.toString()
    }

    @TaskAction
    void doTaskAction() {
        println("proguard.gradle, LogProguardRuleTask, doTaskAction()")
        logger.debug("proguard.gradle, LogProguardRuleTask, doTaskAction()")

        if (project.name != projectName) {
            return
        }

        if (!project.hasProperty("LOG_LEVEL")) {
            return
        }

        logger.debug("gradle param log level: ${currentLogLevel}")

        for (def i = 0; i < allowedLogLevels.size(); i++) {
            if (allowedLogLevels.keySet()[i] != currentLogLevel.toUpperCase()) {
                removeLogLevels.add(allowedLogLevels.values()[i])
            } else {
                break
            }
        }

        logger.debug("proguard log level: " + removeLogLevels)

        updateProguardFile()
    }

}

def genLogProguardFileTask = tasks.register("genLogProguardFile", LogProguardRuleTask) {
    projectName = "app"
    proguardClassList = ["android.util.Log",
                         "com.adealink.frame.log.Log"]

    currentLogLevel = System.getenv("LOG_LEVEL")
    if (currentLogLevel == null || currentLogLevel == "") {
        currentLogLevel = project.hasProperty("LOG_LEVEL") ? project.property("LOG_LEVEL") : "NONE"
    }

    logProguardFile = new File(project.buildFile.getParent() + File.separator + "proguard-log.pro")
}

// remove low level log before compile, since proguard can't remove the concat log clearly
class RemoveConcatLogTask extends DefaultTask {

    @Input
    String projectName

    @Input
    String[] proguardClassList

    @Input
    String currentLogLevel

    private HashMap<String, String> allowedLogLevels

    RemoveConcatLogTask() {
        allowedLogLevels = [VERBOSE: "v",
                            DEBUG  : "d",
                            INFO   : "i",
                            WARN   : "w",
                            ERROR  : "e"]
    }

    @TaskAction
    void doTaskAction() {
        if (project.name != projectName) {
            return
        }

        def paramLevel = ""
        for (int i = 0; i < allowedLogLevels.size(); i++) {
            if (allowedLogLevels.keySet()[i] != currentLogLevel.toUpperCase()) {
                paramLevel += allowedLogLevels.values()[i] + " "
            } else {
                break
            }
        }

        def paramClass = ""
        for (def logClass : proguardClassList) {
            paramClass += logClass.split('\\.')[-1] + " "
        }

        if (paramClass.length() > 0 && paramLevel.length() > 0) {
            println("proguard.gradle, RemoveConcatLogTask, doTaskAction, python proguard-log paramClass:" + paramClass + " paramLevel:" + paramLevel)
//            project.exec {
//                workingDir "."
//                commandLine "python3", "proguard-log.py", "-c " + paramClass, "-l " + paramLevel
//            }
        }
    }
}

def emptyConcatLogStringTask = tasks.register("emptyConcatLogString", RemoveConcatLogTask) {
    projectName = "app"

    proguardClassList = ["android.util.Log",
                         "com.adealink.frame.log.Log"]

    currentLogLevel = System.getenv("LOG_LEVEL")
    if (currentLogLevel == null || currentLogLevel == "") {
        currentLogLevel = project.hasProperty("LOG_LEVEL") ? project.property("LOG_LEVEL") : "NONE"
    }
}

android.applicationVariants.configureEach {
    if (it.buildType.name != "debug") {
        it.preBuildProvider.configure {
            dependsOn emptyConcatLogStringTask
        }
    }
}

tasks.named("preBuild").configure {
    dependsOn genLogProguardFileTask
}

