# Recipe DAG: chocolate chip cookies
# Source: Jenna Barnard, "BEST Chocolate Chip Cookies" (instructions paraphrased)
#
# Changes from the original:
#   - UK terms and units. The gram weights are as published; cups and "spooned and leveled" are gone.
#     all purpose flour > plain flour, baking soda > bicarbonate of soda, granulated > caster sugar,
#     semisweet chips > dark chocolate chips, baking sheet > baking tray, 350F > 180°C / 160°C fan / gas 4.
#   - 3/4 tsp kosher salt > 1/2 tsp fine sea salt, because fine salt packs denser.
#   - 1 US large egg > 1 UK medium, which is the same size (about 55g).
#   - The 60ml scoop stands in for the 2oz scoop and 1/4 cup; the ball weights are worked out from the dough total.
#   - The original lists melting and cooling the butter as prep. It's a step here. Its times and the
#     other hands-on times are our estimates, except the 1 to 2 minute whisk.
#   - The count chips pick the cookie size, not the amount of dough: 9 large or 12 regular, baked in two batches
#     on one tray (5 + 4 or 6 + 6). Baking time follows the size.

recipe:
  id: chocolate_chip_cookies
  code: choc-chip-cookies   # short URL: /choc-chip-cookies
  category: Sweet
  title: Chocolate chip cookies
  yield: { servings: 9, unit: cookie, options: [9, 12] }

inputs:
  n: { label: Cookies from this dough }

derived:
  batch_1: "=ceil(n / 2)"
  batch_2: "=n - batch_1"
  ball: "=round(765 / n / 5) * 5"
  large: "=(12 - n) / 3"       # 1 for 9 large cookies, 0 for 12 regular
  bake_min: "=10 + 2 * large"
  bake_max: "=12 + 3 * large"

resources:
  cook:        { kind: cook,   capacity: 1 }
  oven:        { kind: oven,   capacity: 1, state: { key: temperature, setup: 12m } }
  small_pan:   { kind: vessel, capacity: 1, name: small pan }
  medium_bowl: { kind: vessel, capacity: 1, name: medium bowl }
  large_bowl:  { kind: vessel, capacity: 1, name: large mixing bowl }
  whisk:       { kind: tool,   capacity: 1 }
  spatula:     { kind: tool,   capacity: 1, name: silicone spatula }
  scoop:       { kind: tool,   capacity: 1, name: 60ml cookie scoop }
  baking_tray: { kind: vessel, capacity: 1, name: large baking tray }
  wire_rack:   { kind: rack,   capacity: 1 }

products:
  flour:         { kind: ingredient, qty: { amount: 170, unit: g }, name: plain flour }
  bicarb:        { kind: ingredient, qty: { amount: 0.5, unit: tsp }, name: bicarbonate of soda }
  baking_powder: { kind: ingredient, qty: { amount: 0.5, unit: tsp } }
  salt:          { kind: ingredient, qty: { amount: 0.5, unit: tsp }, name: fine sea salt }
  butter:        { kind: ingredient, qty: { amount: 112, unit: g }, name: unsalted butter }
  brown_sugar:   { kind: ingredient, qty: { amount: 100, unit: g }, name: light brown soft sugar }
  caster_sugar:  { kind: ingredient, qty: { amount: 70, unit: g } }
  vanilla:       { kind: ingredient, qty: { amount: 2, unit: tsp }, name: vanilla extract }
  egg:           { kind: ingredient, qty: { amount: 1, unit: medium } }
  chips:         { kind: ingredient, qty: { amount: 250, unit: g }, name: dark chocolate chips }
  extra_chips:   { kind: ingredient, name: "extra chocolate chips, for topping" }
  flaky_salt:    { kind: ingredient, name: "flaky sea salt, for topping" }

  oven_ready:    { kind: intermediate, name: hot oven, state: 180°C / 160°C fan / gas 4 }
  tray_lined:    { kind: intermediate, name: lined baking tray, vessel: baking_tray, hold: { max: 24h } }
  dry_mix:       { kind: intermediate, name: dry ingredients, vessel: medium_bowl, hold: { max: 4h } }
  butter_melted: { kind: intermediate, name: melted butter, vessel: small_pan, hold: { max: 5m, then: starts to cool } }
  butter_cooled: { kind: intermediate, name: cooled melted butter, state: slightly warm at most, vessel: small_pan, hold: { max: 30m, then: starts to set } }
  sugar_paste:   { kind: intermediate, name: butter and sugar paste, vessel: large_bowl, hold: { max: 15m } }
  wet_mix:       { kind: intermediate, name: wet mix, vessel: large_bowl, hold: { max: 15m } }
  dough:         { kind: intermediate, name: cookie dough, vessel: large_bowl, hold: { max: 30m } }
  balls_1:       { kind: intermediate, name: first batch on the tray, vessel: baking_tray, hold: { max: 10m } }
  dough_rest:    { kind: intermediate, name: rest of the dough, vessel: large_bowl, hold: { max: 30m } }
  baked_1:       { kind: intermediate, name: first batch from the oven, vessel: baking_tray, hold: { max: 1m } }
  on_rack_1:     { kind: intermediate, name: first batch on the rack, vessel: wire_rack }
  tray_free:     { kind: intermediate, name: baking tray, vessel: baking_tray }
  balls_2:       { kind: intermediate, name: second batch on the tray, vessel: baking_tray, hold: { max: 10m } }
  baked_2:       { kind: intermediate, name: second batch from the oven, vessel: baking_tray, hold: { max: 1m } }
  topped_2:      { kind: intermediate, name: second batch, topped, vessel: baking_tray, hold: { max: 1m } }
  cookies:       { kind: final, state: slightly warm, vessel: wire_rack }

steps:
  preheat:
    title: Preheat the oven
    text: Set the oven to 180°C (160°C fan) / gas mark 4.
    outputs: [oven_ready]
    phases:
      - { kind: active, duration: 15s }
      - { kind: passive, duration: 12m }
    uses: [{ resource: oven, requires: { temperature: 180 } }]

  line_tray:
    title: Line the tray
    text: Line a large baking tray with baking parchment.
    outputs: [tray_lined]
    phases: [{ kind: active, duration: 1m }]
    uses: [baking_tray]

  whisk_dry:
    title: Whisk the dry ingredients
    text: In a medium bowl, whisk together the flour, bicarbonate of soda, baking powder and salt. Set aside.
    inputs: [flour, bicarb, baking_powder, salt]
    outputs: [dry_mix]
    phases: [{ kind: active, duration: 1m }]
    uses: [medium_bowl, whisk]

  melt_butter:
    title: Melt the butter
    text: Melt the butter in a small pan over a low heat, then take it off the heat.
    inputs: [butter]
    outputs: [butter_melted]
    phases: [{ kind: active, duration: 2m }]
    done_when: just melted, not bubbling
    uses: [small_pan]

  cool_butter:
    title: Cool the butter
    text: Leave the butter to cool. It can be slightly warm when you use it, but not hot.
    inputs: [butter_melted]
    outputs: [butter_cooled]
    phases: [{ kind: passive, duration: 10m, timer: true }]
    done_when: only slightly warm to the touch

  whisk_sugars:
    title: Whisk the butter and sugars
    text: In a large mixing bowl, whisk the cooled butter with both sugars vigorously for 1 to 2 minutes.
    inputs: [butter_cooled, brown_sugar, caster_sugar]
    outputs: [sugar_paste]
    phases: [{ kind: active, duration: { min: 1m, expected: 2m, max: 2m } }]
    done_when: it has turned into a paste
    uses: [large_bowl, whisk]

  add_egg:
    title: Add the egg and vanilla
    text: Whisk in the egg and vanilla.
    inputs: [sugar_paste, egg, vanilla]
    outputs: [wet_mix]
    phases: [{ kind: active, duration: 1m }]
    done_when: smooth
    uses: [whisk]

  fold:
    title: Fold in the flour and chocolate
    text: Tip in the dry ingredients and fold with a spatula. While a few streaks of flour remain, add the chocolate chips, then keep folding. Don't overmix.
    inputs: [wet_mix, dry_mix, chips]
    outputs: [dough]
    phases: [{ kind: active, duration: 2m }]
    done_when: chips evenly spread and the flour just blended in
    uses: [spatula]

  scoop_1:
    title: Scoop the first batch
    text: Scoop $batch_1 ball(s) of dough, about $ball g each, onto the tray, well spaced. If you're making 9, a 60ml cookie scoop or 4 tablespoons is about right.
    inputs: [dough, tray_lined]
    outputs: [balls_1, dough_rest]
    phases: [{ kind: active, duration: 2m }]
    uses: [scoop]

  bake_1:
    title: Bake the first batch
    text: Bake for $bake_min to $bake_max minutes, the shorter time for a gooier cookie and the longer for a more well-done one.
    inputs: [balls_1, oven_ready]
    outputs: [baked_1]
    phases:
      - { kind: active, duration: 15s }
      - { kind: passive, duration: { min: "=bake_min", expected: "=(bake_min + bake_max) / 2", max: "=bake_max" }, timer: true }
    done_when: a golden ring around the edge, but pale and puffed in the centre
    uses: [{ resource: oven, requires: { temperature: 180 } }]

  finish_1:
    title: Top the first batch
    text: If they've spread too much, nudge the sides in with a fork straight away. Top with a few extra chocolate chips and a sprinkle of flaky salt, then move to a wire rack.
    inputs: [baked_1, extra_chips, flaky_salt]
    outputs: [on_rack_1, tray_free]
    phases: [{ kind: active, duration: 2m }]
    uses: [wire_rack]

  scoop_2:
    title: Scoop the second batch
    text: Scoop the remaining $batch_2 ball(s) of dough onto the same tray and parchment, well spaced.
    inputs: [dough_rest, tray_free]
    outputs: [balls_2]
    phases: [{ kind: active, duration: 2m }]
    uses: [scoop]

  bake_2:
    title: Bake the second batch
    text: Bake for $bake_min to $bake_max minutes, as before.
    inputs: [balls_2, oven_ready]
    outputs: [baked_2]
    phases:
      - { kind: active, duration: 15s }
      - { kind: passive, duration: { min: "=bake_min", expected: "=(bake_min + bake_max) / 2", max: "=bake_max" }, timer: true }
    done_when: a golden ring around the edge, but pale and puffed in the centre
    uses: [{ resource: oven, requires: { temperature: 180 } }]

  finish_2:
    title: Top the second batch
    text: Nudge in any spread sides with a fork, then top with the extra chocolate chips and flaky salt.
    inputs: [baked_2, extra_chips, flaky_salt]
    outputs: [topped_2]
    phases: [{ kind: active, duration: 1m }]

  cool:
    title: Cool the cookies
    text: Move the second batch to the rack and leave everything to cool for about 20 minutes. They're best slightly warm, while the chips are still melty.
    inputs: [topped_2, on_rack_1]
    outputs: [cookies]
    phases:
      - { kind: active, duration: 30s }
      - { kind: passive, duration: 20m }
    done_when: slightly warm, chips still melty
    uses: [wire_rack]
