; Fieldtest raw-buf comprehensive .4 (Axes 1+2+3 — Int buffer, an
; own->own fill helper across a function boundary, plus TWO distinct
; borrow-receiver helpers composed over the same buffer).
;
; Task an LLM author is naturally given: "fill a buffer of N slots with
; the Fibonacci sequence, then report both the total and the index of
; the largest element." The natural decomposition is three helpers:
;   - `fill`  : (own RawBuf, Int) -> own RawBuf   (loop/recur, runtime N)
;   - `total` : (borrow RawBuf) -> Int            (read loop off .size)
;   - `argmax`: (borrow RawBuf) -> Int            (read loop, tracks idx)
; and a main that threads the owned buffer through `fill`, then borrows
; it TWICE in sequence (`total buf`, then `argmax buf`) — the natural
; "compute several summaries of one read-only buffer" shape.
;
; This stresses the #46 borrow-receiver fix under composition: two
; independent borrows of the same owned binder, each a helper that does
; multiple RawBuf.get / RawBuf.size calls on its borrow parameter. The
; prior rawbuf_1 had a single borrow helper; this has two, called back
; to back on the same buffer, with the buffer still owned (and dropped)
; by main afterwards.
;
; Fib(0..5) = 1,1,2,3,5,8  (seeding fib(0)=fib(1)=1).
;   total  = 1+1+2+3+5+8 = 20
;   argmax = index 5 (value 8 is largest)
; Expected stdout: "20" then "5".

(module rbx_4_int_two_borrow_helpers

  (fn fill
    (doc "Fill slot i with fib(i) for i in 0..n. Linear own->own.")
    (type (fn-type (params (own (con RawBuf (con Int))) (own (con Int))) (ret (own (con RawBuf (con Int))))))
    (params buf n)
    (body
      ; Seed slots 0 and 1 to 1, then each later slot = sum of prior two,
      ; read back from the buffer itself via RawBuf.get on the owned `b`.
      (loop (b (con RawBuf (con Int)) buf) (i (con Int) 0)
        (if (app ge i n)
            b
            (recur (app RawBuf.set b i
                     (if (app le i 1)
                         1
                         (app + (app RawBuf.get b (app - i 1))
                                (app RawBuf.get b (app - i 2)))))
                   (app + i 1))))))

  (fn total
    (doc "Sum every slot, borrow receiver.")
    (type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (own (con Int)))))
    (params buf)
    (body
      (loop (acc (con Int) 0) (i (con Int) 0)
        (if (app ge i (app RawBuf.size buf))
            acc
            (recur (app + acc (app RawBuf.get buf i))
                   (app + i 1))))))

  (fn argmax
    (doc "Index of the largest slot, borrow receiver. Tracks (best_i, best_v).")
    (type (fn-type (params (borrow (con RawBuf (con Int)))) (ret (own (con Int)))))
    (params buf)
    (body
      (loop (best_i (con Int) 0) (best_v (con Int) (app RawBuf.get buf 0)) (i (con Int) 0)
        (if (app ge i (app RawBuf.size buf))
            best_i
            (if (app gt (app RawBuf.get buf i) best_v)
                (recur i (app RawBuf.get buf i) (app + i 1))
                (recur best_i best_v (app + i 1)))))))

  (fn main
    (type (fn-type (params) (ret (own (con Unit))) (effects IO)))
    (params)
    (body
      (let buf (new RawBuf (con Int) 6)
        (let buf (app fill buf 6)
          (seq (seq (app print (app total buf)) (do io/print_str "\n"))
               (seq (app print (app argmax buf)) (do io/print_str "\n"))))))))
