// summary : ZIO learning - using standard ZIO config system - documentation
// keywords : scala, zio, learning, pure-functional, config, @testable
// publish : gist
// authors : David Crosson
// license : Apache NON-AI License Version 2.0 (https://raw.githubusercontent.com/non-ai-licenses/non-ai-licenses/main/NON-AI-APACHE2)
// id : e3a249ac-ac51-47d4-b070-267e985c1a1f
// created-on : 2023-04-29T21:52:36+02:00
// managed-by : https://github.com/dacr/code-examples-manager
// run-with : scala-cli $file

// ---------------------
//> using scala "3.4.2"
//> using dep "dev.zio::zio:2.0.13"
//> using dep "dev.zio::zio-config:4.0.0-RC14"
// ---------------------

import zio.*
import zio.config.*

case class DatabaseConfig(
  name: String,
  host: String,
  port: Int,
  mapSize: Int
)

object DatabaseConfig {
  val config: Config[DatabaseConfig] =
    ((Config.string("name").withDefault("example") ?? "database name") ++
      (Config.string("host").withDefault("127.0.0.1") ?? "database host") ++
      (Config.int("port").withDefault(42).validate("port must be > 0 and < 65535")(v => v > 0 && v < 65535) ?? "database port") ++
      (Config.int("mapSize").withDefault(10_000) ?? "allocated maximum memory mapped size "))
      .to[DatabaseConfig]
      .nested("database")
}

object Encapsulated extends ZIOAppDefault {
  // -------------------------------------------------------------
  val logic = for {
    myConf <- ZIO.config(DatabaseConfig.config)
    docs    = generateDocs(DatabaseConfig.config)
    _      <- Console.printLine(docs.toTable.toGithubFlavouredMarkdown)
    _      <- Console.printLine(myConf)
    _      <- Console.printLine("Customizable using properties database.name, database.host & database.port")
    _      <- Console.printLine("Customizable using environment variables DATABASE_NAME, DATABASE_HOST & DATABASE_PORT")
  } yield ()

  // -------------------------------------------------------------
  override def run = {
    logic
  }
}

Encapsulated.main(Array.empty)