/*
 * root.gradle
 *
 * This source file is part of the FoundationDB open source project
 *
 * Copyright 2015-2018 Apple Inc. and the FoundationDB project authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.security.MessageDigest

/**
 * Build configuration specially for the root project only.
 */

apply plugin: 'project-reports'
//apply plugin: 'release'

htmlDependencyReport {
    projects = project.allprojects
}
dependencyReport {
    projects = project.allprojects
}

def generateMD5(File file) {
    def digest = MessageDigest.getInstance("MD5")
    file.withInputStream() { is ->
        byte[] buffer = new byte[8192]
        int read = 0
        while ((read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }
    }
    byte[] md5sum = digest.digest()
    BigInteger bigInt = new BigInteger(1, md5sum)
    bigInt.toString(16).padLeft(32, '0')
}

task checksumsVerify {

    doLast {
        def checksumsFile = file('.checksum')
        def failed = []
        checksumsFile.eachLine { line ->
            if (line.startsWith("#")) { return }
            def parts = line.split('\\s+')
            def name = parts[0]
            def checksum = parts[1]
            def md5 = generateMD5(file(name))
            if (!md5.equalsIgnoreCase(checksum)) {
                failed.add(name)
            }

        }
        if (!failed.empty) {
            throw new RuntimeException("Some MD5 sums failed to verify: " + failed)
        }
    }
}

apply plugin: 'jacoco'

tasks.register('codeCoverageReport', JacocoReport) {
    def coverageSubprojects = subprojects.findAll { sp ->
        sp.name != 'examples' &&
            sp.name != 'fdb-record-layer-core-shaded' &&
            sp.name != 'fdb-record-layer-jmh'
    }

    // Add dependencies on test tasks that generate jacoco execution data
    // use mustRunAfter so that we can download the jacoco/jar artifacts from parallel jobs
    // in our pull_request workflow, and then run codeCoverageReport to merge, but this
    // enforces the order, so that if you run the tests and codeCoverageReport in the same
    // run (such as our nightly builds), gradle won't complain about implicit dependencies.
    def t = coverageSubprojects.collectMany { sp ->
        sp.tasks.withType(Test)
    }
    t.addAll(coverageSubprojects.collectMany { sp ->
        sp.tasks.withType(Jar)
    })

    mustRunAfter t
    def data = coverageSubprojects.collectMany { sp ->
        sp.tasks.withType(Test).collect { testTask -> testTask.jacoco.destinationFile }
    }
    executionData data

    // Not much consistency in naming these.
    def exclusions = [
        "**/*Proto.class", "**/*Proto\$*.class",
        "**/planprotos/*", "**/eventprotos/*",
        "**/generated/*", "**/grpc/v1/**/*"
    ]

    classDirectories.setFrom(coverageSubprojects.collect { sp ->
        sp.layout.buildDirectory.file("libs/${sp.name}-${sp.version}.jar").map { jf ->
            zipTree(jf).matching {
                exclude exclusions
            }
        }
    })

    // These can come from source tree.
    sourceDirectories.setFrom(files(coverageSubprojects.sourceSets.main.allSource.srcDirs))

    reports {
        xml.required = true
        html.required = true
    }
}
