package db

import io.getquill.*
import io.getquill.jdbczio.Quill
import zio.*
import javax.sql.DataSource

/** Quill PostgreSQL context with ZIO integration
  *
  * Provides compile-time SQL query validation via Quill. Exports two layers:
  *   - dataSourceLayer: HikariCP-managed connection pool configured from application.conf
  *   - quillLayer: Quill PostgreSQL context with SnakeCase naming strategy
  *
  * Usage:
  * {{{
  * import db.QuillContext.*
  *
  * def findUser(email: String) =
  *   run(query[SummerUser].filter(_.email == lift(email)))
  *     .provide(quillLive)
  * }}}
  *
  * IMPORTANT: Never use "io" as a variable name in files importing Quill
  * (conflicts with io.getquill package).
  */
object QuillContext {

  /** DataSource layer from HikariCP configuration
    *
    * Reads configuration from "hikari" prefix in application.conf.
    * Uses separate prefix from "database" to avoid conflict with ZIO config.
    * HikariCP manages the connection pool.
    */
  val dataSourceLayer: ZLayer[Any, Throwable, DataSource] =
    Quill.DataSource.fromPrefix("hikari")

  /** Quill PostgreSQL context with snake_case naming
    *
    * Converts Scala camelCase field names to PostgreSQL snake_case columns.
    * Example: passwordHash -> password_hash
    */
  val quillLayer: ZLayer[DataSource, Nothing, Quill.Postgres[SnakeCase]] =
    Quill.Postgres.fromNamingStrategy(SnakeCase)

  /** Combined layer for full Quill PostgreSQL access
    *
    * Provides both DataSource and Quill context.
    * Use this when you need to run queries.
    */
  val quillLive: ZLayer[Any, Throwable, Quill.Postgres[SnakeCase]] =
    dataSourceLayer >>> quillLayer

}
