plugins {
    id 'java'
    id('eclipse')
    id('idea')
    id('org.springframework.boot') version "2.2.1.RELEASE"
    id('io.spring.dependency-management') version "1.1.4"
    id('com.google.protobuf') version "0.9.1"
    id('jacoco')
    id('org.sonarqube') version "2.8"
    id('com.diffplug.spotless') version "5.16.0"
}

sourceCompatibility = 11
targetCompatibility = 11

configurations {
    testCompile
    compile.exclude module: 'spring-boot-starter-logging'
}

repositories {
    mavenCentral()
    jcenter()
}

def grpcVersion = '1.47.0'
def protobufVersion = '3.21.2'
def activemqVersion = '5.12.0'

// Spring dependency versions are managed by the io.spring.dependency-management plugin.
// Appropriate versions will be pulled based on the spring boot version specified in the
// spring-boot-gradle-plugin.
dependencies {
    implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
    implementation group: 'com.google.guava', name: 'guava', version: '26.0-android'
    implementation group: 'com.sun.mail', name: 'mailapi', version: '1.5.4'
    implementation group: 'commons-lang', name: 'commons-lang', version: '2.6'
    implementation group: 'io.grpc', name: 'grpc-all', version: "${grpcVersion}"
    implementation group: 'org.apache.activemq', name: 'activemq-pool', version: activemqVersion
    implementation group: 'org.apache.velocity', name: 'velocity', version: '1.7'
    implementation group: 'org.jdom', name: 'jdom', version: '1.1.3'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
    implementation group: 'org.springframework', name: 'spring-context-support'
    implementation group: 'org.springframework', name: 'spring-jms'
    implementation group: 'org.quartz-scheduler', name: 'quartz', version: '2.2.1', { exclude group: 'c3p0', module: 'c3p0' }
    implementation group: 'org.postgresql', name: 'postgresql', version: '42.2.2'
    implementation group: 'com.google.protobuf', name: 'protobuf-java', version: "${protobufVersion}"
    implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.16.0'
    implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.16.0'
    implementation group: 'io.sentry', name: 'sentry-log4j2', version: '7.11.0'
    implementation group: 'io.prometheus', name: 'simpleclient', version: '0.16.0'
    implementation group: 'io.prometheus', name: 'simpleclient_servlet', version: '0.16.0'

    protobuf files("../proto/src/")

    testImplementation group: 'junit', name: 'junit', version: '4.12'
    testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test'
    testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.8.0'
    testImplementation group: 'io.zonky.test', name: 'embedded-postgres', version: '2.0.1'
    testImplementation group: 'io.zonky.test.postgres', name: 'embedded-postgres-binaries-linux-arm64v8', version: '15.2.0'
    testImplementation group: 'org.flywaydb', name: 'flyway-core', version: '5.2.0'

    // Use newer version of Postgres for tests: https://github.com/zonkyio/embedded-postgres/issues/78
    implementation enforcedPlatform('io.zonky.test.postgres:embedded-postgres-binaries-bom:11.13.0')
}

compileJava {
    dependsOn generateProto
    options.compilerArgs << "-Xlint:all" << "-Werror"
}

compileTestJava {
    dependsOn generateProto
    options.compilerArgs << "-Xlint:all" << "-Werror"
}

protobuf {
    protoc {
        // The protoc compiler
        artifact = 'com.google.protobuf:protoc:3.21.2'
    }
    plugins {
        grpc {
            // Generate gRPC stubs.
            artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
        }
    }
    generateProtoTasks {
        ofSourceSet('main')*.plugins {
            // Apply the "grpc" plugin to all sources.
            grpc { }
        }
    }
    generatedFilesBaseDir = "${projectDir}/src/compiled_protobuf"
}

// Help IDEs recognize the generated code.
sourceSets {
    main {
        java {
            srcDirs += 'src/compiled_protobuf/main/java'
            srcDirs += 'src/compiled_protobuf/main/grpc'
        }
    }
    test {
        resources.srcDirs = ["src/test/resources"]
    }
}

bootJar {
    baseName = 'cuebot'
    mainClassName = 'com.imageworks.spcue.CuebotApplication'
}

jacoco {
    toolVersion = "0.8.11"
}

jacocoTestReport {
    reports {
        // XML is used by SonarCloud. HTML is generated if you want to generate a human-readable
        // report locally. Reports are placed in build/reports/jacoco/.
        xml.enabled true
        html.enabled true
    }

    // Exclude files from test coverage.
    afterEvaluate {
        classDirectories.setFrom(files(classDirectories.files.collect {
            fileTree(dir: it,
                    exclude: [
                            // Exclude proto files' generated Java code.
                            'com/imageworks/spcue/grpc/**'])
        }))
    }
}

sonarqube {
    properties {
        property "sonar.java.source", "11"
        property "sonar.host.url", "https://sonarcloud.io"
        property "sonar.organization", "academysoftwarefoundation"
        property "sonar.projectKey", "AcademySoftwareFoundation_OpenCue_Cuebot"
        property "sonar.projectName", "OpenCue Cuebot"
        // NOTE: sonar.login must be provided manually, like:
        //   ./gradlew sonarqube -Dsonar.login=<login key>

        property "sonar.issue.ignore.multicriteria", "j1,j2"

        // Incompatible @Transactional requirements
        // It's claimed this causes runtime exceptions but we don't see such issues.
        property "sonar.issue.ignore.multicriteria.j1.ruleKey", "java:S2229"
        property "sonar.issue.ignore.multicriteria.j1.resourceKey", "**/*.java"

        // Null pointers
        // DAO classes make heavy use of getJdbcTemplate() which triggers this rule, but is
        // never null in practice.
        property "sonar.issue.ignore.multicriteria.j2.ruleKey", "java:S2259"
        property "sonar.issue.ignore.multicriteria.j2.resourceKey", "src/main/java/com/imageworks/spcue/dao/**/*.java"
    }
}

tasks.withType(AbstractArchiveTask) {
    preserveFileTimestamps = false
    reproducibleFileOrder = true
}

test {
    testLogging {
        testLogging {
            exceptionFormat = 'full'
        }
   }
}

spotless {
    java {
        targetExclude 'src/compiled_protobuf/**'
        toggleOffOn()
        eclipse().configFile('jdtls.xml')
    }
}
