---
prelude: |
  require "net/imap"

  require "./test/lib/profiling_helper"
  include ProfilingHelper

  def init(label = nil, n:, d: 1.5)
    n       = n.to_int
    samples = (1e5.to_i / n).ceil.clamp(1..100)
    domain  = 1..(n*d).floor
    $sets   = Array.new(samples) {
      set = Net::IMAP::SequenceSet.new
      n.times do set << rand(domain) end
      set
    }
    $idxs   = Array.new([10_000, 2 * n].min) { rand(-n..n - 1) }
    $lens   = Array.new([10_000,     n].min) { rand(1..n) }
    $ranges = Array.new([10_000, n * n].min) {
      start = idx
      stop  = start.negative? ? rand(start..-1) : rand(start...n)
      start..stop
    }
    maybe_profile("seqset-slice-#{label}-#{n}") if label
  end

  def set   = $sets.sample
  def idx   = $idxs.sample
  def len   = $lens.sample
  def range = $ranges.sample

  # warmup
  init n: 100
  2000.times do
    set[idx]
    set[range]
    set[idx, len]
  end

benchmark:

  - { name: "(N= 10 )      set[idx]", prelude: "init(:at, n: 1e1)", script: "set[idx]" }
  - { name: "(N=100 )      set[idx]", prelude: "init(:at, n: 1e2)", script: "set[idx]" }
  - { name: "(N=  1K)      set[idx]", prelude: "init(:at, n: 1e3)", script: "set[idx]" }
  - { name: "(N= 10K)      set[idx]", prelude: "init(:at, n: 1e4)", script: "set[idx]" }
  - { name: "(N=100K)      set[idx]", prelude: "init(:at, n: 1e5)", script: "set[idx]" }
  - { name: "(N=  1M)      set[idx]", prelude: "init(:at, n: 1e6)", script: "set[idx]" }

  - { name: "(N= 10 ) set[idx, len]", prelude: "init(:len, n: 1e1)", script: "set[idx, len]" }
  - { name: "(N=100 ) set[idx, len]", prelude: "init(:len, n: 1e2)", script: "set[idx, len]" }
  - { name: "(N=  1K) set[idx, len]", prelude: "init(:len, n: 1e3)", script: "set[idx, len]" }
  - { name: "(N= 10K) set[idx, len]", prelude: "init(:len, n: 1e4)", script: "set[idx, len]" }
  - { name: "(N=100K) set[idx, len]", prelude: "init(:len, n: 1e5)", script: "set[idx, len]" }
  - { name: "(N=  1M) set[idx, len]", prelude: "init(:len, n: 1e6)", script: "set[idx, len]" }

  - { name: "(N= 10 )    set[range]", prelude: "init(:range, n: 1e1)", script: "set[range]" }
  - { name: "(N=100 )    set[range]", prelude: "init(:range, n: 1e2)", script: "set[range]" }
  - { name: "(N=  1K)    set[range]", prelude: "init(:range, n: 1e3)", script: "set[range]" }
  - { name: "(N= 10K)    set[range]", prelude: "init(:range, n: 1e4)", script: "set[range]" }
  - { name: "(N=100K)    set[range]", prelude: "init(:range, n: 1e5)", script: "set[range]" }
  - { name: "(N=  1M)    set[range]", prelude: "init(:range, n: 1e6)", script: "set[range]" }

contexts:
  - name: local
    prelude: |
      $LOAD_PATH.unshift "./lib"
      $allowed_to_profile = true # only profile local code
    require: false
  - name: v0.5.8 # fixes several bugs
    gems:
      net-imap: 0.5.8
    require: false
  - name: v0.4.21 # backports 0.5.8 bugfixes
    gems:
      net-imap: 0.4.21
    require: false
