///|
/// Main Entrypoint for moonbit-auction Demo & Benchmark Execution.
fn main {
  println(
    "=========================================================================",
  )
  println(
    "🚀 moonbit-auction: Market Mechanism Design & Simulation Framework",
  )
  println(
    "=========================================================================\n",
  )

  // 1. Single Item Auctions Demonstration
  println("--- [1] Single-Item Auction Simulation (Vickrey vs First-Price) ---")
  let item = @types.Item::new(
    "item-101",
    "H100 GPU Server Node",
    reserve_price=500.0,
  )

  let vickrey = @single_item.VickreyAuction::new(item)
  let _ = vickrey.submit_bid("bidder-Alice", 1200.0)
  let _ = vickrey.submit_bid("bidder-Bob", 1500.0)
  let _ = vickrey.submit_bid("bidder-Charlie", 1350.0)

  match vickrey.finalize() {
    Ok(outcome) => println(@analytics.explain_allocation(outcome))
    Err(e) => println("Error running Vickrey auction: \{e}")
  }

  // 2. Combinatorial Package Bidding WDP Solver Demonstration
  println("\n--- [2] Combinatorial XOR Bundle Auction (WDP Solver) ---")
  let bundle_items = ["cloud-vm", "storage-bucket", "cdn-bandwidth"]
  let comb_auction = @multi_item.CombinatorialAuction::new(
    bundle_items,
    valuation_type=@types.ValuationType::XOR,
  )

  let _ = comb_auction.submit_bundle_bid(
    "corp-Alpha",
    ["cloud-vm", "storage-bucket"],
    950.0,
  )
  let _ = comb_auction.submit_bundle_bid(
    "corp-Beta",
    ["storage-bucket", "cdn-bandwidth"],
    400.0,
  )
  let _ = comb_auction.submit_bundle_bid("corp-Gamma", ["cdn-bandwidth"], 200.0)

  match comb_auction.solve_wdp() {
    Ok(winning_bundles) => {
      println("WDP Optimal Non-Overlapping Winners:")
      let mut total_rev = 0.0
      for bundle in winning_bundles {
        println(
          "  - Bidder: " +
          bundle.bidder_id +
          " | Amount: " +
          bundle.bid_amount.to_string(),
        )
        total_rev = total_rev + bundle.bid_amount
      }
      println("Total Package Revenue: \{total_rev}")
    }
    Err(e) => println("Error solving WDP: \{e}")
  }

  // 3. Ad Slot Keyword Auction Demonstration (GSP vs VCG)
  println("\n--- [3] Search Ad Keyword Auction (GSP Position Pricing) ---")
  let slots = [
    @ad_auction.AdSlot::new("top-slot", 1, 0.25),
    @ad_auction.AdSlot::new("sidebar-slot", 2, 0.10),
  ]
  let gsp = @ad_auction.GspAuction::new(slots, reserve_price=1.0)
  let _ = gsp.submit_bid("brand-TechCorp", 8.0, quality_score=2.0)
  let _ = gsp.submit_bid("brand-FastLogistics", 6.0, quality_score=1.5)
  let _ = gsp.submit_bid("brand-CloudData", 4.0, quality_score=1.0)

  match gsp.finalize() {
    Ok(outcome) => println(@analytics.explain_allocation(outcome))
    Err(e) => println("Error running GSP auction: \{e}")
  }

  // 4. Two-Sided Matching (Gale-Shapley Deferred Acceptance)
  println("\n--- [4] Gale-Shapley Stable Deferred Acceptance Matching ---")
  let da = @matching.DeferredAcceptance::new()
  da.add_proposer("procurement-buyer-1", ["vendor-X", "vendor-Y"])
  da.add_proposer("procurement-buyer-2", ["vendor-X", "vendor-Y"])
  da.add_receiver(
    "vendor-X",
    ["procurement-buyer-2", "procurement-buyer-1"],
    capacity=1,
  )
  da.add_receiver(
    "vendor-Y",
    ["procurement-buyer-1", "procurement-buyer-2"],
    capacity=1,
  )

  let matches = da.solve()
  println("Stable Matching Assignments:")
  matches.each(fn(buyer, seller) { println("  - \{buyer} <===> \{seller}") })

  // 5. Market Simulator & Analytics Report Generation
  println("\n--- [5] Event-Driven Market Simulator & Welfare Report ---")
  let sim_items = [
    @types.Item::new("compute-node", "Edge Node", reserve_price=100.0),
  ]
  let sim_agents = [
    @strategy.BiddingAgent::new(
      "agent-1",
      "Agent 1",
      300.0,
      strategy=@strategy.StrategyType::Truthful,
    ),
    @strategy.BiddingAgent::new(
      "agent-2",
      "Agent 2",
      280.0,
      strategy=@strategy.StrategyType::Shaded(0.9),
    ),
    @strategy.BiddingAgent::new(
      "agent-3",
      "Agent 3",
      250.0,
      strategy=@strategy.StrategyType::AdaptiveEpsilonGreedy(0.1, 0.05),
    ),
  ]

  let simulator = @simulation.MarketSimulator::new(
    sim_items,
    sim_agents,
    mechanism=@simulation.MarketMechanismType::Vickrey,
  )

  let outcomes = simulator.run_simulation(5)
  let metrics = @analytics.analyze_outcomes(outcomes)
  println(@analytics.generate_summary_report(metrics))

  // 6. Reproducible benchmark CLI output. Logical steps are used instead of
  // wall-clock time so results remain comparable across CI runners.
  println("\n--- [6] Reproducible Benchmark Suite ---")
  let suite = @analytics.BenchmarkSuite::new()
  suite.add_case(@analytics.BenchmarkCase::new("small", 8, 4))
  suite.add_case(@analytics.BenchmarkCase::new("medium", 32, 8))
  let benchmark_records = suite.run()
  for record in benchmark_records {
    println(
      "  " +
      record.summary() +
      " digest_length=" +
      record.workload_digest.length().to_string(),
    )
  }
  let dashboard = @analytics.benchmark_dashboard(benchmark_records)
  println(@analytics.KpiDashboard::to_markdown(dashboard))

  println(
    "=========================================================================",
  )
  println("✅ Market Simulation Completed Successfully.")
  println(
    "=========================================================================",
  )
}