
import com.github.jk1.license.render.*
import com.github.jk1.license.filter.ExcludeTransitiveDependenciesFilter
import com.github.jk1.license.filter.LicenseBundleNormalizer
import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
import com.github.jk1.license.render.InventoryMarkdownReportRenderer
import org.jsoup.Jsoup
import org.springframework.boot.gradle.tasks.bundling.BootJar

//import org.gradle.internal.impldep.org.jsoup.Jsoup


buildscript {
	repositories {
		mavenCentral()
	}
	dependencies {
		classpath ("org.jsoup:jsoup:1.18.1")
		// 빌드 스크립트에서 commonmark 라이브러리를 사용할 수 있도록 추가합니다.
		classpath("org.commonmark:commonmark:0.18.0")
	}
}


plugins {
	kotlin("jvm") version "1.9.25"
	kotlin("plugin.spring") version "1.9.25"
	id("org.springframework.boot") version "3.3.4"
	id("io.spring.dependency-management") version "1.1.6"
	id("com.github.jk1.dependency-license-report") version "2.0"

}

group = "kr.lunaticbum.back"
version = "0.0.7-SNAPSHOT"

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(17)
	}
}

configurations {
	compileOnly {
		extendsFrom(configurations.annotationProcessor.get())
	}
}

repositories {
	mavenCentral()

	maven { url = uri("https://repo.spring.io/milestone") }

}

dependencies {
	// [추가] Kotlin BOM(Bill of Materials)을 사용하여 모든 코틀린 라이브러리 버전을 정렬합니다.
	implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.9.25"))

	// --- 기존 의존성 (정리됨) ---
	implementation ("org.slf4j:jcl-over-slf4j")
	implementation ("org.springframework.boot:spring-boot-starter-quartz")
	implementation ("org.apache.tomcat.embed:tomcat-embed-jasper")
	implementation("org.springframework.boot:spring-boot-starter-data-mongodb-reactive")
	implementation("org.springframework.boot:spring-boot-starter-web")
	implementation("org.springframework.boot:spring-boot-starter-webflux")
	implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
	implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
	implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
	implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
	implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6")
	implementation("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
	implementation ("org.jsoup:jsoup:1.18.1")
	implementation ("org.seleniumhq.selenium:selenium-java:4.10.0")
	implementation ("org.commonmark:commonmark:0.18.0")
	implementation ("net.coobird:thumbnailator:0.4.14")
	implementation("org.sejda.imageio:webp-imageio:0.1.6")
	implementation ("com.drewnoakes:metadata-extractor:2.19.0")
	implementation("org.springframework.boot:spring-boot-starter-security")
	compileOnly("org.projectlombok:lombok")
	implementation ("com.google.maps:google-maps-services:2.2.0")
	implementation(platform("org.springframework.ai:spring-ai-bom:1.0.0-M6"))
	implementation("org.springframework.ai:spring-ai-ollama-spring-boot-starter:1.0.0-M6")
	implementation ("org.springframework.ai:spring-ai-qdrant-store-spring-boot-starter")
	implementation ("org.slf4j:slf4j-simple:1.7.25")
	implementation("io.jsonwebtoken:jjwt-api:0.11.5")
	implementation("io.jsonwebtoken:jjwt-impl:0.11.5")
	implementation("io.jsonwebtoken:jjwt-jackson:0.11.5")

	// [수정] 버전 번호를 제거합니다. (BOM이 버전을 관리해 줍니다)
	implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
	implementation("org.jetbrains.kotlin:kotlin-reflect")

	// [수정] Gson 라이브러리 중복 제거 (2.11.0 버전만 남김)
	implementation ("com.google.code.gson:gson:2.11.0")

	annotationProcessor("org.projectlombok:lombok")
	testImplementation("org.springframework.boot:spring-boot-starter-test")
	testImplementation("io.projectreactor:reactor-test")
	testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
	testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}


kotlin {
	compilerOptions {
		freeCompilerArgs.addAll("-Xjsr305=strict")
	}
}
tasks.withType<org.gradle.jvm.tasks.Jar>() {
	duplicatesStrategy = DuplicatesStrategy.EXCLUDE
	exclude("META-INF/BC1024KE.RSA", "META-INF/BC1024KE.SF", "META-INF/BC1024KE.DSA")
	exclude("META-INF/BC2048KE.RSA", "META-INF/BC2048KE.SF", "META-INF/BC2048KE.DSA")
}
tasks.withType<Test> {
	useJUnitPlatform()
}


tasks.jar {
	archiveFileName.set("app.jar")
	manifest {
		attributes["Main-Class"] = "kr.lunaticbum.back.lun.LunApplicationKt"
	}
	configurations["compileClasspath"].forEach { file: File ->
		from(zipTree(file.absoluteFile))
	}
	duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

tasks.jar {

	// Otherwise you'll get a "No main manifest attribute" error
	manifest {
		attributes["Main-Class"] = "kr.lunaticbum.back.lun.LunApplicationKt"
	}

	// To avoid the duplicate handling strategy error
	duplicatesStrategy = DuplicatesStrategy.EXCLUDE

	// To add all of the dependencies otherwise a "NoClassDefFoundError" error
	from(sourceSets.main.get().output)

	dependsOn(configurations.runtimeClasspath)
	from({
		configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
	})
}

// ✅ licenseReport는 이전과 동일하게 Markdown을 생성하도록 둡니다.

licenseReport {

	outputDir = "$projectDir/build/licenses"
	renderers = arrayOf(InventoryMarkdownReportRenderer())
//	filters = arrayOf(com.github.jk1.license.filter.LicenseBundleNormalizer(), com.github.jk1.license.filter.ExcludeTransitiveDependenciesFilter())
}

tasks.register("updateLicensePage") {
	dependsOn("generateLicenseReport")

	doLast {
//		file("$projectDir/build/licenses").listFiles().forEach {
//			println("${it.absolutePath}: ${it.name}")
//		}
		// ... 로그 출력 로직은 그대로 유지 ...
		println("🚀 'updateLicensePage' 태스크를 시작합니다.")

		val licenseMarkdownFile = file("$projectDir/build/licenses/licenses.md")
		val targetHtmlFile = file("src/main/resources/templates/content/licenses.html")

		println("   - 원본 마크다운 파일: ${licenseMarkdownFile.path}")
		println("   - 대상 HTML 파일: ${targetHtmlFile.path}")

		if (!licenseMarkdownFile.exists()) {
			throw GradleException("❌ 라이선스 마크다운 파일이 생성되지 않았습니다. '${licenseMarkdownFile.path}'")
		}

		val licenseMarkdown = licenseMarkdownFile.readText()
		println("   - 마크다운 파일을 성공적으로 읽었습니다. (내용 길이: ${licenseMarkdown.length})")

		val parser = Parser.builder().build()
		val renderer = HtmlRenderer.builder().build()
		val licenseHtml = renderer.render(parser.parse(licenseMarkdown))
		println("   - 마크다운을 HTML로 변환했습니다. (HTML 길이: ${licenseHtml.length})")


		// ✅ Jsoup으로 HTML 파일을 파싱합니다.
		val doc = Jsoup.parse(targetHtmlFile, "UTF-8")

		// ✅ CSS 선택자를 이용해 ID가 'license-content-container'인 태그를 선택하고
		//    그 내부 HTML을 생성된 라이선스 내용으로 교체합니다.
		doc.selectFirst("#license-content-container")?.html(licenseHtml)

		println("   - HTML 파일 내 placeholder div의 내용을 교체했습니다.")

		// ✅ 변경된 HTML 내용을 파일에 다시 씁니다.
		targetHtmlFile.writeText(doc.outerHtml())

		println("✅ 라이선스 정보(HTML)가 '${targetHtmlFile.name}' 파일에 성공적으로 업데이트되었습니다.")
	}
}

// 'build' 태스크 실행 시 이 작업이 자동으로 수행되도록 연결
// [수정 전] tasks.build { dependsOn(tasks.getByName("updateLicensePage")) }
tasks.named("build") { // [수정 후] 'build' 태스크를 더 안전하게 참조합니다.
	dependsOn(tasks.named("updateLicensePage"))
}

tasks.named("bootJar") { // [수정 후] 'build' 태스크를 더 안전하게 참조합니다.
	dependsOn(tasks.named("updateLicensePage"))
}

// 기본 bootJar 태스크의 설정을 가져오기 위한 참조
val bootJar by tasks.getting(BootJar::class)
//
//// 'prod' 프로필이 내장된 JAR를 빌드하는 최종 태스크 정의
//tasks.register<BootJar>("bootJarProd") {
//	group = "build"
//	description = "Builds a production JAR that defaults to the 'prod' profile."
//	archiveClassifier.set("prod")
//
//	// --- 필수 설정 복사 ---
//	// 1. Main 클래스 설정 복사
//	mainClass.set(bootJar.mainClass)
//	// 2. Classpath 설정 복사
//	classpath = bootJar.classpath
//	// 3. Target Java Version 설정 복사 (이번 오류 해결)
//	targetJavaVersion.set(bootJar.targetJavaVersion)
//
//	manifest {
//		attributes["Spring-Profiles-Active"] = "prod"
//	}
//}

// "local" 프로파일용 JAR를 빌드하는 작업
tasks.register<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJarLocal") {
	group = "build"
	description = "로컬 환경용 JAR 파일을 빌드합니다 ('local' 프로파일 적용)."
	archiveClassifier.set("local") // 파일 이름에 local 접미사 추가 (e.g., app-local.jar)

	// 메인 클래스와 클래스패스는 기본 bootJar 설정을 따라갑니다.
	mainClass.set(tasks.bootJar.get().mainClass)
	classpath = tasks.bootJar.get().classpath
	targetJavaVersion.set(bootJar.targetJavaVersion)
	// 'resources' 폴더의 모든 파일을 복사하되...
	from("src/main/resources") {
		include("**/*")
		// prod 설정 파일은 제외합니다.
		exclude("application-prod.properties")
		// local 설정 파일의 이름을 application.properties로 변경합니다.
		rename("application-local.properties", "application.properties")
	}
}

// "prod" 프로파일용 JAR를 빌드하는 작업
tasks.register<org.springframework.boot.gradle.tasks.bundling.BootJar>("bootJarProd") {
	group = "build"
	description = "운영 환경용 JAR 파일을 빌드합니다 ('prod' 프로파일 적용)."
	archiveClassifier.set("prod") // 파일 이름에 prod 접미사 추가 (e.g., app-prod.jar)

	// 메인 클래스와 클래스패스는 기본 bootJar 설정을 따라갑니다.
	mainClass.set(tasks.bootJar.get().mainClass)
	classpath = tasks.bootJar.get().classpath
	targetJavaVersion.set(bootJar.targetJavaVersion)
	// 'resources' 폴더의 모든 파일을 복사하되...
	from("src/main/resources") {
		include("**/*")
		// local 설정 파일은 제외합니다.
		exclude("application-local.properties")
		// prod 설정 파일의 이름을 application.properties로 변경합니다.
		rename("application-prod.properties", "application.properties")
	}
}


// 🚀 1. 명령어를 실행할 새로운 Exec 태스크 정의
tasks.register<Exec>("runCommandAfterProdJar") {
	group = "build"
	description = "prod JAR 빌드 후 실행할 명령어를 정의합니다."

	// 이 태스크는 bootJarProd가 성공해야만 의미가 있으므로, 의존성을 명시해주는 것이 좋습니다.
	dependsOn(tasks.named("bootJarProd"))

	// 실행할 OS 명령어와 인자를 설정합니다.
	// 예시 1: Docker 이미지 빌드
	commandLine("docker", "buildx","buildx","--platform","linux/amd64", "-t", "lunaticbum/testjar:0.025", ".")

	// 예시 2: 빌드된 JAR 파일을 특정 서버로 복사
	// commandLine("scp", "build/libs/your-app-name-prod.jar", "user@server:/path/to/deploy")

	// 예시 3: 간단한 셸 스크립트 실행
	// commandLine("./deploy.sh")

	// 필요하다면 작업 디렉토리를 설정할 수 있습니다.
	// workingDir = rootDir
//	doLast {
//		println("prod JAR 빌드가 완료되었습니다. 추가 명령어를 실행합니다.")
//		exec {
//			commandLine("docker", "push", "lunaticbum/testjar:0.025")
//			// commandLine("echo", "Hello from doLast!")
//		}
//	}
}

// 🚀 2. bootJarProd 태스크가 끝나면 위에서 정의한 태스크를 실행하도록 연결
//tasks.named("bootJarProd") {
//	finalizedBy(tasks.named("runCommandAfterProdJar"))
//}

//
//// 'build' 태스크 실행 시 이 작업이 자동으로 수행되도록 연결
//tasks.build {
//	dependsOn(tasks.getByName("updateLicensePage"))
//}