// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.

/////////////////////////////////////////////////////////////////////////////
// Project Settings
/////////////////////////////////////////////////////////////////////////////

name := "workflow-core"


enablePlugins(JavaAppPackaging)

// Enable semanticdb for Scalafix
ThisBuild / semanticdbEnabled := true
ThisBuild / semanticdbVersion := scalafixSemanticdb.revision

// Manage dependency conflicts by always using the latest revision
ThisBuild / conflictManager := ConflictManager.latestRevision

// Restrict parallel execution of tests to avoid conflicts
Global / concurrentRestrictions += Tags.limit(Tags.Test, 1)


/////////////////////////////////////////////////////////////////////////////
// Compiler Options
/////////////////////////////////////////////////////////////////////////////

// Scala compiler options
Compile / scalacOptions ++= Seq(
  "-Xelide-below", "WARNING",       // Turn on optimizations with "WARNING" as the threshold
  "-feature",                       // Check feature warnings
  "-deprecation",                   // Check deprecation warnings
  "-Ywarn-unused:imports"           // Check for unused imports
)


/////////////////////////////////////////////////////////////////////////////
// ScalaPB Configuration
/////////////////////////////////////////////////////////////////////////////

// Exclude some proto files
PB.generate / excludeFilter := "scalapb.proto"

// Set the protoc version for ScalaPB
ThisBuild / PB.protocVersion := "3.19.4"

// ScalaPB code generation for .proto files
Compile / PB.targets := Seq(
  scalapb.gen(singleLineToProtoString = true) -> (Compile / sourceManaged).value
)

// Mark the ScalaPB-generated directory as a generated source root
Compile / managedSourceDirectories += (Compile / sourceManaged).value

// ScalaPB library dependencies
libraryDependencies ++= Seq(
  "com.thesamet.scalapb" %% "scalapb-runtime" % scalapb.compiler.Version.scalapbVersion % "protobuf",
  "com.thesamet.scalapb" %% "scalapb-json4s" % "0.12.0"  // For ScalaPB 0.11.x
)

// Enable protobuf compilation in Test
Test / PB.protoSources += PB.externalSourcePath.value


/////////////////////////////////////////////////////////////////////////////
// Test-related Dependencies
/////////////////////////////////////////////////////////////////////////////

val testcontainersVersion = "0.44.1"

libraryDependencies ++= Seq(
  "org.scalamock" %% "scalamock" % "5.2.0" % Test,                  // ScalaMock
  "org.scalatest" %% "scalatest" % "3.2.15" % Test,                 // ScalaTest
  "junit" % "junit" % "4.13.2" % Test,                              // JUnit
  "com.novocode" % "junit-interface" % "0.11" % Test,               // SBT interface for JUnit
  "com.dimafeng" %% "testcontainers-scala-scalatest" % testcontainersVersion % Test,   // Testcontainers ScalaTest integration
  "com.dimafeng" %% "testcontainers-scala-minio" % testcontainersVersion % Test        // MinIO Testcontainer Scala integration
)


/////////////////////////////////////////////////////////////////////////////
// Jackson-related Dependencies
/////////////////////////////////////////////////////////////////////////////

val jacksonVersion = "2.18.6"
libraryDependencies ++= Seq(
  "javax.validation" % "validation-api" % "2.0.1.Final",
  "com.fasterxml.jackson.core" % "jackson-databind" % jacksonVersion,        // Jackson Databind
  "com.fasterxml.jackson.module" % "jackson-module-kotlin" % jacksonVersion % Test,   // Jackson Kotlin Module
  "com.fasterxml.jackson.datatype" % "jackson-datatype-jdk8" % jacksonVersion % Test, // Jackson JDK8 Datatypes
  "com.fasterxml.jackson.datatype" % "jackson-datatype-jsr310" % jacksonVersion % Test, // Jackson JSR310
  "com.fasterxml.jackson.datatype" % "jackson-datatype-joda" % jacksonVersion % Test,   // Jackson Joda
  "com.fasterxml.jackson.module" % "jackson-module-jsonSchema" % jacksonVersion,      // JSON Schema Module
  "com.fasterxml.jackson.module" %% "jackson-module-scala" % jacksonVersion,           // Scala Module
  "com.fasterxml.jackson.module" % "jackson-module-no-ctor-deser" % jacksonVersion     // No Constructor Deserializer
)

/////////////////////////////////////////////////////////////////////////////
// Arrow related
val arrowVersion = "15.0.2"
val nettyVersion = "4.1.96.Final"
val arrowDependencies = Seq(
  // https://mvnrepository.com/artifact/org.apache.arrow/flight-grpc
  "org.apache.arrow" % "flight-grpc" % arrowVersion,
  // https://mvnrepository.com/artifact/org.apache.arrow/flight-core
  "org.apache.arrow" % "flight-core" % arrowVersion
)

libraryDependencies ++= arrowDependencies

// Netty dependency overrides to ensure compatibility with Arrow
// Arrow 14.0.1 requires Netty 4.1.96.Final for proper memory allocation
// The chunkSize field issue occurs when Netty versions are mismatched
dependencyOverrides ++= Seq(
  "io.netty" % "netty-all" % nettyVersion,
  "io.netty" % "netty-buffer" % nettyVersion,
  "io.netty" % "netty-codec" % nettyVersion,
  "io.netty" % "netty-codec-http" % nettyVersion,
  "io.netty" % "netty-codec-http2" % nettyVersion,
  "io.netty" % "netty-codec-socks" % nettyVersion,
  "io.netty" % "netty-common" % nettyVersion,
  "io.netty" % "netty-handler" % nettyVersion,
  "io.netty" % "netty-handler-proxy" % nettyVersion,
  "io.netty" % "netty-resolver" % nettyVersion,
  "io.netty" % "netty-transport" % nettyVersion,
  "io.netty" % "netty-transport-classes-epoll" % nettyVersion,
  "io.netty" % "netty-transport-native-epoll" % nettyVersion,
  "io.netty" % "netty-transport-native-unix-common" % nettyVersion
)

/////////////////////////////////////////////////////////////////////////////
// Iceberg-related Dependencies
/////////////////////////////////////////////////////////////////////////////
val excludeJersey = ExclusionRule(organization = "com.sun.jersey")
val excludeGlassfishJersey = ExclusionRule(organization = "org.glassfish.jersey")
val excludeSlf4j = ExclusionRule(organization = "org.slf4j")
val excludeJetty = ExclusionRule(organization = "org.eclipse.jetty")
val excludeJsp = ExclusionRule(organization = "javax.servlet.jsp")
val excludeXmlBind = ExclusionRule(organization = "javax.xml.bind")
val excludeJackson = ExclusionRule(organization = "com.fasterxml.jackson.core")
val excludeJacksonModule = ExclusionRule(organization = "com.fasterxml.jackson.module")

libraryDependencies ++= Seq(
  "org.apache.iceberg" % "iceberg-api" % "1.7.1",
  "org.apache.iceberg" % "iceberg-parquet" % "1.7.1" excludeAll(
    excludeJackson,
    excludeJacksonModule
  ),
  "org.apache.iceberg" % "iceberg-core" % "1.7.1" excludeAll(
    excludeJackson,
    excludeJacksonModule
  ),
  "org.apache.iceberg" % "iceberg-data" % "1.7.1" excludeAll(
    excludeJackson,
    excludeJacksonModule
  ),
  "org.apache.iceberg" % "iceberg-aws" % "1.7.1" excludeAll(
    excludeJackson,
    excludeJacksonModule
  ),
  "org.apache.hadoop" % "hadoop-common" % "3.3.1" excludeAll(
    excludeXmlBind,
    excludeGlassfishJersey,
    excludeJersey,
    excludeSlf4j,
    excludeJetty,
    excludeJsp,
    excludeJackson,
    excludeJacksonModule
  ),
  "org.apache.hadoop" % "hadoop-mapreduce-client-core" % "3.3.1" excludeAll(
    excludeXmlBind,
    excludeGlassfishJersey,
    excludeJersey,
    excludeSlf4j,
    excludeJetty,
    excludeJsp,
    excludeJackson,
    excludeJacksonModule
  ),
  "org.postgresql" % "postgresql" % "42.7.3"
)

/////////////////////////////////////////////////////////////////////////////
// Additional Dependencies
/////////////////////////////////////////////////////////////////////////////

libraryDependencies ++= Seq(
  "com.github.sisyphsu" % "dateparser" % "1.0.11",                    // DateParser
  "com.google.guava" % "guava" % "31.1-jre",                          // Guava
  "org.ehcache" % "sizeof" % "0.4.3",                                 // Ehcache SizeOf
  "org.jgrapht" % "jgrapht-core" % "1.4.0",                           // JGraphT Core
  "com.typesafe.scala-logging" %% "scala-logging" % "3.9.5",          // Scala Logging
  "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.0.202109080827-r",  // jgit
  "org.apache.commons" % "commons-vfs2" % "2.9.0",                     // for FileResolver throw VFS-related exceptions
  "io.lakefs" % "sdk" % "1.51.0",                                     // for lakeFS api calls
  "com.typesafe" % "config" % "1.4.6",                                 // config reader
  "org.apache.commons" % "commons-jcs3-core" % "3.2",                 // Apache Commons JCS
  "software.amazon.awssdk" % "s3" % "2.29.51" excludeAll(
    ExclusionRule(organization = "io.netty")
  ),
  "software.amazon.awssdk" % "auth" % "2.29.51" excludeAll(
    ExclusionRule(organization = "io.netty")
  ),
  "software.amazon.awssdk" % "regions" % "2.29.51" excludeAll(
    ExclusionRule(organization = "io.netty")
  ),
  "software.amazon.awssdk" % "sts" % "2.29.51" excludeAll(
    ExclusionRule(organization = "io.netty")
  ),
)