///|
/// A short tour of the library, runnable with `moon run cmd/main`.
///
/// Each section shows an operation whose result is not what a naive
/// "dates are numbers" model would predict.
fn main {
  section("The core types")
  let date = try! @temporal.PlainDate::try_new(2025, 3, 1)
  let time = try! @temporal.PlainTime::try_new(hour=11, minute=16, second=10)
  show("date", date.to_string())
  show("time", time.to_string())
  show("combined", (try! date.to_plain_date_time(time~)).to_string())
  show(
    "instant",
    (try! @temporal.Instant::of_string("2025-03-01T11:16:10Z")).to_string(),
  )
  section("Adding a month depends on where you start")
  let one_month = try! @temporal.Duration::of(months=1)
  for year in [2023, 2024] {
    let jan31 = try! @temporal.PlainDate::try_new(year, 1, 31)
    show("\{jan31} + P1M", (try! jan31.add(one_month)).to_string())
  }
  section("One gap, several correct descriptions")
  let start = try! @temporal.PlainDate::try_new(2019, 1, 1)
  let end = try! @temporal.PlainDate::try_new(2023, 9, 15)
  for unit in [@temporal.DateTimeUnit::Year, Month, Week, Day] {
    let difference = try! start.until(
      end,
      settings=@temporal.DifferenceSettings::new(largest_unit=unit),
    )
    show("largest unit \{unit}", difference.to_string())
  }
  section("Rounding modes disagree, on purpose")
  let noon_ish = try! @temporal.PlainTime::try_new(
    hour=12,
    minute=34,
    second=56,
  )
  for mode in [@temporal.RoundingMode::Floor, Ceil, HalfExpand, Trunc] {
    let rounded = try! noon_ish.round(
      @temporal.RoundingOptions::new(smallest_unit=Minute, rounding_mode=mode),
    )
    show("\{noon_ish} to the minute, \{mode}", rounded.to_string())
  }
  section("The same instant reads differently in each zone")
  let zoned = try! @temporal.ZonedDateTime::of_string(
    "2025-03-01T11:16:10Z[UTC]", @temporal.utc_only_provider,
  )
  for offset_minutes in [0, -360, 330] {
    let zone = @temporal.TimeZone::OffsetZone(
      @temporal.UtcOffset::from_minutes(offset_minutes),
    )
    let shifted = try! zoned.with_time_zone(zone, @temporal.utc_only_provider)
    show(zone.identifier(), shifted.to_string())
  }
}

///|
fn section(title : String) -> Unit {
  println("\n\{title}")
  println("-".repeat(title.length()))
}

///|
fn show(label : String, value : String) -> Unit {
  println("  \{label}: \{value}")
}