from fixtures import soloTool as uut, songPool, mockPlayer, testSongs

def test_playerControls(uut, mockPlayer):
    assert not mockPlayer.playing
    assert not uut.playing
    uut.play()
    assert mockPlayer.playing
    assert uut.playing
    uut.pause()
    assert not mockPlayer.playing
    assert not uut.playing

    assert mockPlayer.rate == 1.0
    uut.rate = 0.5
    assert mockPlayer.rate == 0.5
    assert uut.rate == 0.5

    assert mockPlayer.position == 0.0
    uut.position = 0.5
    assert mockPlayer.position == 0.5
    assert uut.position == 0.5

    assert mockPlayer.volume == 1.0
    uut.volume = 0.5
    assert mockPlayer.volume == 0.5
    assert uut.volume == 0.5

def test_sanitizePlaybackRate(uut):
    # Initial value
    assert uut.rate == 1.0

    # Valid rates are >= 0.0, invalid is ignored
    uut.rate = -0.1
    assert uut.rate == 1.0

    uut.rate = 0.0
    assert uut.rate == 0.0
    
    uut.rate = 0.0001
    assert uut.rate == 0.0001

    uut.rate = 150.0
    assert uut.rate == 150.0

def test_sanitizePlaybackPosition(uut):
    # Initial value
    assert uut.position == 0.0

    # Valid positions are in [0, 1], invalid is limited
    uut.position = 0.2
    assert uut.position == 0.2

    uut.position = -0.1
    assert uut.position == 0.0

    uut.position = 1.0
    assert uut.position == 1.0

    uut.position = 0.4
    assert uut.position == 0.4

    uut.position = 1.5
    assert uut.position == 1.0

def test_sanitizePlaybackVolume(uut):
    # Initial value
    assert uut.volume == 1.0

    # Valid volumes are >= 0.0, invalid is ignored
    uut.volume = -0.1
    assert uut.volume == 1.0

    uut.volume = 0.0
    assert uut.volume == 0.0

    uut.volume = 1.0
    assert uut.volume == 1.0

    uut.volume = 150.0
    assert uut.volume == 150.0

def test_playingStateNotification(uut, mockPlayer, testSongs):
    uut.addSong(testSongs[0])

    called = False
    receivedValue = None
    def callback(value):
        nonlocal called, receivedValue
        called = True
        receivedValue = value

    uut.registerPlayingStateCallback(callback)

    assert not mockPlayer.playing
    assert not called

    uut.play()
    assert called
    assert receivedValue == True
    called = False
    uut.play()
    assert not called

    uut.pause()
    assert called
    assert receivedValue == False
    called = False
    uut.pause()
    assert not called

def test_playbackVolumeNotification(uut, mockPlayer, testSongs):
    uut.addSong(testSongs[0])

    called = False
    receivedValue = None
    def callback(value):
        nonlocal called, receivedValue
        called = True
        receivedValue = value

    uut.registerVolumeCallback(callback)

    assert not called

    uut.volume = 0.3
    assert called
    assert receivedValue == 0.3
    called = False

    uut.volume = 0.3
    assert not called

def test_playbackRateNotification(uut, mockPlayer, testSongs):
    uut.addSong(testSongs[0])

    called = False
    receivedValue = None
    def callback(value):
        nonlocal called, receivedValue
        called = True
        receivedValue = value

    uut.registerRateCallback(callback)

    assert not called

    uut.rate = 0.5
    assert called
    assert receivedValue == 0.5
    called = False

    uut.rate = 0.5
    assert not called