load('@stdlib//internal/graph.star', 'graph')
load('@stdlib//internal/luci/common.star', 'builder_ref', 'keys', 'triggerer')


### Toy builder+poller model.


def builder(bucket, name, triggered_by=[], triggers=[]):
  k = keys.builder(bucket, name)
  graph.add_node(k)
  ref = builder_ref.add(k)
  trg = triggerer.add(k)
  for t in triggered_by:
    graph.add_edge(keys.triggerer(t), ref)
  for t in triggers:
    graph.add_edge(trg, keys.builder_ref(t))
  return k


def poller(bucket, name, triggers=[]):
  k = keys.gitiles_poller(bucket, name)
  graph.add_node(k)
  trg = triggerer.add(k)
  for t in triggers:
    graph.add_edge(trg, keys.builder_ref(t))
  return k


def targets(poller_key):
  return [n.key for n in triggerer.targets(graph.node(poller_key))]


### Test cases.


def test_triggers():
  p1 = poller('buck', 'p1', triggers=['buck1/b1', 'b2'])
  p2 = poller('buck', 'p2', triggers=['b2'])
  p3 = poller('buck', 'p3')
  b1 = builder('buck1', 'b1')
  b2 = builder('buck2', 'b2')
  __native__.graph().finalize()
  assert.eq(targets(p1), [b1, b2])
  assert.eq(targets(p2), [b2])
  assert.eq(targets(p3), [])


def test_triggered_by():
  p1 = poller('buck', 'p1')
  p2 = poller('buck', 'p2')
  b1 = builder('buck1', 'b1', triggered_by=['buck/p1'])
  b2 = builder('buck2', 'b2', triggered_by=['p1', 'p2'])
  __native__.graph().finalize()
  assert.eq(targets(p1), [b1, b2])
  assert.eq(targets(p2), [b2])


def test_both_directions_not_an_error():
  p1 = poller('buck', 'p1', triggers=['buck1/b1', 'b2'])
  b1 = builder('buck1', 'b1', triggered_by=['p1'])
  b2 = builder('buck2', 'b2', triggered_by=['buck/p1'])
  __native__.graph().finalize()
  assert.eq(targets(p1), [b1, b2])


def test_ambiguous_builder_ref():
  p = poller('buck', 'p', triggers=['b'])
  b1 = builder('buck1', 'b')
  b2 = builder('buck2', 'b')
  __native__.graph().finalize()
  assert.fails(lambda: targets(p),
      'ambiguous reference "b" in core.gitiles_poller\("buck/p"\), possible variants:\n' +
      '  core.builder\("buck1/b"\)\n' +
      '  core.builder\("buck2/b"\)'
  )


def test_ambiguous_triggerer():
  p1 = poller('buck1', 'p')
  p2 = poller('buck2', 'p')
  bp = builder('buck3', 'p')
  b = builder('buck', 'b', triggered_by=['p'])
  __native__.graph().finalize()
  err_re = (
      'ambiguous reference "p" in core.builder\("buck/b"\), possible variants:\n' +
      '  core.gitiles_poller\("buck1/p"\)\n' +
      '  core.gitiles_poller\("buck2/p"\)\n' +
      '  core.builder\("buck3/p"\)'
  )
  assert.fails(lambda: targets(p1), err_re)
  assert.fails(lambda: targets(p2), err_re)


def test_triggering_cycle():
  builder('buck', 'b1', triggers=['b2'])
  assert.fails(
      lambda: builder('buck', 'b2', triggers=['b1']), 'introduces a cycle')


### Test runner.


def with_clean_state(cbs):
  for cb in cbs:
    __native__.clear_state()
    __native__.fail_on_errors()
    cb()


with_clean_state([
    test_triggers,
    test_triggered_by,
    test_both_directions_not_an_error,
    test_ambiguous_builder_ref,
    test_ambiguous_triggerer,
    test_triggering_cycle,
])
