plugins {
  id 'org.springframework.boot' version '3.5.5'
  id 'io.spring.dependency-management' version '1.1.7'
  id 'org.owasp.dependencycheck' version '12.1.6'
  id 'com.diffplug.spotless' version '8.0.0'
  id 'eclipse'
  id 'jacoco'
  id 'idea'
  id 'java'
}

group = 'com.developersboard'
version = '0.0.1-SNAPSHOT'

java {
  toolchain {
    languageVersion = JavaLanguageVersion.of(21)
  }
  // You can uncomment this to include javadoc jar generation
  //  withJavadocJar()

  // You can comment this line to exclude source jar
  withSourcesJar()
}


configurations {
  compileOnly {
    extendsFrom annotationProcessor
  }
}

repositories {
  mavenCentral()
}

ext {
  set('jjwtVersion', '0.13.0')
  set('springDocVersion', '2.8.13')
  set('javadocScribeVersion', '0.15.0')
  set('mapstructVersion', '1.6.3')
  set('awsSdkS3Version', '2.31.45')
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-mail'
  implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6'
  implementation 'org.springframework.boot:spring-boot-starter-security'
  implementation 'org.springframework.boot:spring-boot-starter-actuator'
  implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
  implementation 'org.springframework.boot:spring-boot-starter-data-rest'
  implementation 'org.springframework.boot:spring-boot-starter-validation'

  // Dev Tools
  compileOnly 'org.projectlombok:lombok'
  annotationProcessor 'org.projectlombok:lombok'
  developmentOnly 'org.springframework.boot:spring-boot-devtools'
  annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'

  implementation 'org.ehcache:ehcache'
  implementation 'org.hibernate.orm:hibernate-jcache'
  implementation 'org.ehcache:ehcache-transactions:3.10.8'

  // Utilities
  implementation 'org.jsoup:jsoup:1.21.2'
  implementation "io.jsonwebtoken:jjwt-api:${jjwtVersion}"
  runtimeOnly "io.jsonwebtoken:jjwt-impl:${jjwtVersion}"
  runtimeOnly "io.jsonwebtoken:jjwt-jackson:${jjwtVersion}"
  implementation 'commons-io:commons-io:2.20.0'
  implementation 'net.datafaker:datafaker:2.5.1'
  implementation 'com.google.code.gson:gson:2.13.2'
  implementation 'commons-validator:commons-validator:1.10.0'
  implementation 'com.github.darrachequesne:spring-data-jpa-datatables:7.1.0'

  // Documentation and API Tools
  implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${springDocVersion}"
  implementation "org.springdoc:springdoc-openapi-starter-common:${springDocVersion}"
  annotationProcessor "com.github.therapi:therapi-runtime-javadoc-scribe:${javadocScribeVersion}"
  runtimeOnly "com.github.therapi:therapi-runtime-javadoc:${javadocScribeVersion}"

  // Database and File Storage Tools
  implementation 'com.h2database:h2'
  runtimeOnly 'org.postgresql:postgresql'
  implementation 'org.liquibase:liquibase-core'
  implementation 'org.hibernate.orm:hibernate-envers'
  implementation "software.amazon.awssdk:s3:${awsSdkS3Version}"
  implementation files('libs/hypersistence-optimizer-2.6.3-jakarta.jar')

  // MapStruct for Object Mapping
  implementation "org.mapstruct:mapstruct:${mapstructVersion}"
  annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}"

  // Webjars
  implementation 'org.webjars:jquery:3.7.1'
  implementation 'org.webjars:bootstrap:5.3.5'
  implementation 'org.webjars:jquery-ui:1.14.1'
  implementation 'org.webjars:datatables:2.3.0'
  implementation 'org.webjars:font-awesome:6.7.2'
  implementation 'org.webjars:webjars-locator:0.52'
}

testing {
  //noinspection GroovyAssignabilityCheck
  suites {
    configureEach {
      useJUnitJupiter()

      dependencies {
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        implementation 'io.findify:s3mock_2.13:0.2.6'
        implementation 'com.icegreen:greenmail-junit5:2.1.3'
        implementation 'com.jparams:to-string-verifier:1.4.8'
        implementation 'nl.jqno.equalsverifier:equalsverifier:4.0'
        implementation 'org.springframework.security:spring-security-test'
        implementation 'org.springframework.boot:spring-boot-starter-test'
        runtimeOnly 'org.junit.platform:junit-platform-launcher'
      }
    }
    //noinspection GroovyAssignabilityCheck
    integrationTest(JvmTestSuite) {
      sources.java.srcDirs = ['src/integrationTest/java']
      sources.resources.srcDirs = ['src/integrationTest/resources']
      dependencies {
        implementation project()
        implementation sourceSets.test.output

        implementation 'org.springframework.boot:spring-boot-testcontainers'
        implementation "software.amazon.awssdk:s3:${awsSdkS3Version}"
        implementation 'org.testcontainers:junit-jupiter'
        implementation 'org.testcontainers:postgresql'
      }
      targets {
        configureEach {
          testTask.configure {
            shouldRunAfter(test)
            finalizedBy 'jacocoTestReport'
            // Fail the 'test' task on the first test failure
            failFast = true
            // If no active profile is set, use integration-test is the active profile
            environment 'SPRING_PROFILES_ACTIVE', System.getenv("SPRING_PROFILES_ACTIVE") ?: "integration-test"
          }
        }
      }
    }
  }
}

configurations {
  integrationTestImplementation.extendsFrom testImplementation
}

tasks.named('check') {
  dependsOn(testing.suites.integrationTest)
}

tasks.named('bootBuildImage') {
  builder = 'paketobuildpacks/builder-jammy-base:latest'
}

tasks.withType(JavaCompile).configureEach {
  options.compilerArgs += ['-Xlint:deprecation']
  dependsOn 'spotlessApply'
}

jacocoTestReport {
  executionData(fileTree(layout.buildDirectory).include("jacoco/*.exec"))
  reports {
    xml.required = true
    html.required = true
    csv.required = true
  }

  afterEvaluate {
    classDirectories.setFrom(files(classDirectories.files.collect {
      fileTree(dir: it, exclude: [
          "**/exception/*",
          "**/enums/*",
          "**/constant/*",
          "**/config/*",
          "**/backend/bootstrap/*",
          "**/Mock*.class",
          "**/*DtoMapperImpl.class",
      ])
    }))
  }
}

spotless {
  format 'misc', {
    // define the files to apply `misc` to
    target '*.gradle', '*.md', '.gitignore'

    // define the steps to apply to those files
    trimTrailingWhitespace()
    leadingTabsToSpaces()
    endWithNewline()
  }

  java {

    // define the steps to apply to those files
    trimTrailingWhitespace()
    leadingTabsToSpaces()
    endWithNewline()
    removeUnusedImports()
  }
}
