local assert = require 'luassert'
local say    = require("say")
local function greater_than(state, arguments)
  local min, val = arguments[1], arguments[2]
  return min < val
end
assert:register('assertion', 'greater_than', greater_than, 'assertion.greater_than.positive', 'assertion.greater_than.negative')
say:set_namespace("en")
say:set("assertion.greater_than.positive", "Expected %s < %s")
say:set("assertion.greater_than.negative", "Expected %s >= %s")

describe("abletonlink library", function()
  local link = require 'abletonlink'

  it("exports a _VERSION", function()
    -- asset.is.equal('1.0.0', link._VERSION)
  end)

  it("can create and destroy link objects", function()
    local l = link.create(120)
    l:destroy()
    assert.has.error(function() l:is_enabled() end)
  end)

  it("can be enabled and disabled", function()
    local l = link.create(120)
    assert.is_false(l:is_enabled())
    l:enable()
    assert.is_true(l:is_enabled())

    l:enable(false)
    assert.is_false(l:is_enabled())
    l:enable(true)
    assert.is_true(l:is_enabled())
  end)

  it("start/stop sync can be enabled and disabled", function()
    local l = link.create(120)
    assert.is_false(l:is_start_stop_sync_enabled())
    l:enable_start_stop_sync()
    assert.is_true(l:is_start_stop_sync_enabled())

    l:enable_start_stop_sync(false)
    assert.is_false(l:is_start_stop_sync_enabled())
    l:enable_start_stop_sync(true)
    assert.is_true(l:is_start_stop_sync_enabled())
  end)

  test("num_peers()", function()
    local a, b = link.create(120), link.create(120)
    assert.equal(0, a:num_peers())
    assert.equal(0, b:num_peers())

    a:enable()
    b:enable()

    -- stall a bit for connections to succeed
    for i=1,10000 do
      i = math.random()
    end

    assert.greater_than(0, a:num_peers())
    assert.greater_than(0, b:num_peers())
  end)

  test("clock_micros()", function()
    local l = link.create(120)

    local last = 0

    for i=1,10 do
      local next = l:clock_micros()
      assert.is.number(next)
      assert.is.greater_than(last, next)
      last = next
    end
  end)

  describe("app state", function()
    it("can be created and destroyed", function()
      local s = link.create_session_state()
      s:tempo()
      s:destroy()
      assert.has.error(function() s:tempo() end)
    end)

    it("can get/set tempo", function()
      local s = link.create_session_state()
      s:set_tempo(120, 0)
      assert.is.equal(120, s:tempo())
      s:set_tempo(90, 0)
      assert.is.equal(90, s:tempo())
    end)
  end)
end)
