-- extract player names
local function player_names(players)
    local names = {}

    for _, player in ipairs(players) do
        names[player:get_player_name()] = true
    end
    return names
end

-- count keys in set
local function key_count(set)
    local count = 0

    for key in pairs(set) do count = count + 1 end
    return count
end


-- Test suite for mods/lobby/tdc.lua
TestLobbyTdc = {}
    function TestLobbyTdc:setUp()
        lobby.game = {}
        lobby.map = {}
        mtmock.privs = {
            ['admin'] = {
                server=true, traitor_dev=true, builder=true, creative=true,
                worldeditor=true, pro_player=true, multihome=true
            },
            ['noob'] = {
                server=false, traitor_dev=false, builder=false, creative=false,
                worldeditor=false, pro_player=false, multihome=false
            },
            ['player'] = {
                server=false, traitor_dev=false, builder=false, creative=false,
                worldeditor=false, pro_player=true, multihome=false
            },
            ['builder'] = {
                server=false, traitor_dev=false, builder=true, creative=true,
                worldeditor=true, pro_player=true, multihome=false
            },
            ['b_visitor'] = {
                server=false, traitor_dev=false, builder=true, creative=false,
                worldeditor=false, pro_player=true, multihome=false
            },
        }
    end

    -- does tdc.privs_footprint() create the fooprint as expected?
    function TestLobbyTdc:testPrivsFootprint()
        lu.assertEquals(tdc.privs_footprint(mtmock.privs['admin']), 'stbcwpm')
        lu.assertEquals(tdc.privs_footprint(mtmock.privs['noob']), '-------')
        lu.assertEquals(tdc.privs_footprint(mtmock.privs['player']), '-----p-')
        lu.assertEquals(tdc.privs_footprint(mtmock.privs['builder']), '--bcwp-')
        lu.assertEquals(tdc.privs_footprint(mtmock.privs['b_visitor']), '--b--p-')
    end

    -- does tdc.active_players_matching() find the right set of players?
    function TestLobbyTdc:testActivePlayersMatching()
        local admin = mtmock.add_player('admin', true)
        local noob = mtmock.add_player('noob')
        local player = mtmock.add_player('player')
        local builder = mtmock.add_player('builder', true)
        local b_visitor = mtmock.add_player('b_visitor', true)

        local players = tdc.active_players_matching('r')
        local names = player_names(players)
        lu.assertEquals(#players, 3)
        lu.assertIsNil(names.admin)
        lu.assertIsNil(names.noob)
        lu.assertIsTrue(names.player)
        lu.assertIsTrue(names.builder)
        lu.assertIsTrue(names.b_visitor)

        local players = tdc.active_players_matching('noob')
        names = player_names(players)
        lu.assertEquals(#players, 1)
        lu.assertIsNil(names.admin)
        lu.assertIsTrue(names.noob)
        lu.assertIsNil(names.player)
        lu.assertIsNil(names.builder)
        lu.assertIsNil(names.b_visitor)
    end

    -- does tdc.active_mapids_matching() find the expected maps?
    function TestLobbyTdc:testActiveMapidsMatching()
        -- simulate players visiting maps
        lobby.map.map_zero = 0
        lobby.map.map_one = 2
        lobby.map.map_two = 5
        lobby.map.map_three = 42
        lobby.map.map_four = 4
        lobby.map.map_five = -2
        lobby.map.map_toby = 23

        local mapids = tdc.active_mapids_matching('one')
        lu.assertEquals(key_count(mapids), 1)
        lu.assertIsTrue(mapids.map_one)

        mapids = tdc.active_mapids_matching('zero')
        lu.assertEquals(key_count(mapids), 0)

        mapids = tdc.active_mapids_matching('five')
        lu.assertEquals(key_count(mapids), 0)

        mapids = tdc.active_mapids_matching('map')
        lu.assertEquals(key_count(mapids), 5)
        lu.assertIsTrue(mapids.map_one)
        lu.assertIsTrue(mapids.map_two)
        lu.assertIsTrue(mapids.map_three)
        lu.assertIsTrue(mapids.map_four)
        lu.assertIsTrue(mapids.map_toby)
    end

    -- does tdc.active_mapids_matching() add the lobby to the result list
    -- if it matches the search expression?
    function TestLobbyTdc:testActiveMapidsMatchingTreatsLobbyAsPseudoMap()
        -- simulate some players visiting maps
        lobby.map.my_hobby_map = 12
        lobby.map.mapping_is_lobotomy = 4
        lobby.map.toby_1 = 17

        local mapids = tdc.active_mapids_matching('bby')
        lu.assertEquals(key_count(mapids), 2)
        lu.assertIsTrue(mapids.my_hobby_map)
        lu.assertIsTrue(mapids.lobby)

        local mapids = tdc.active_mapids_matching('lob')
        lu.assertEquals(key_count(mapids), 2)
        lu.assertIsTrue(mapids.mapping_is_lobotomy)
        lu.assertIsTrue(mapids.lobby)

        local mapids = tdc.active_mapids_matching('lobby')
        lu.assertEquals(key_count(mapids), 1)
        lu.assertIsTrue(mapids.lobby)

        local mapids = tdc.active_mapids_matching('tob')
        lu.assertEquals(key_count(mapids), 1)
        lu.assertIsTrue(mapids.toby_1)
    end

    -- does tdc.players_visiting() find all players playing the same game?
    function TestLobbyTdc:testPlayersVisitingFindsAllPlayersInAMap()
        -- fake two player sessions
        mtmock.add_player('team1_pl1')
        mtmock.add_player('team1_pl2')
        mtmock.add_player('team1_pl3')
        mtmock.add_player('team2_pl1')
        mtmock.add_player('team2_pl2')
        mtmock.add_player('team2_pl3')
        mtmock.add_player('team2_pl4')
        lobby.game.team1_pl1 = 'map_one'
        lobby.game.team1_pl2 = 'map_one_solo'
        lobby.game.team1_pl3 = 'map_one'
        lobby.game.team2_pl1 = 'map_two'
        lobby.game.team2_pl2 = 'map_two_ghost'
        lobby.game.team2_pl3 = 'map_two'
        lobby.game.team2_pl4 = 'map_two_ghost'

        local visitors = tdc.players_visiting({['map_one'] = true})
        lu.assertEquals(#visitors, 3)
        for _, player in ipairs(visitors) do
            lu.assertStrContains(player:get_player_name(), 'team1')
        end

        visitors = tdc.players_visiting({['map_two'] = true})
        lu.assertEquals(#visitors, 4)
        for _, player in ipairs(visitors) do
            lu.assertStrContains(player:get_player_name(), 'team2')
        end
    end

    -- does tdc.players_visiting() find builders currently in a map?
    function TestLobbyTdc:testPlayersVisitingFindsBuildersInAMap()
        mtmock.add_player('bld_1', true)
        mtmock.add_player('bld_2', true)
        lobby.game.bld_1 = 'map_one_builder'
        lobby.game.bld_2 = 'map_two_builder'

        local visitors = tdc.players_visiting({['map_one'] = true})
        lu.assertEquals(#visitors, 1)
        lu.assertEquals(visitors[1]:get_player_name(), 'bld_1')

        local visitors = tdc.players_visiting({['map_two'] = true})
        lu.assertEquals(#visitors, 1)
        lu.assertEquals(visitors[1]:get_player_name(), 'bld_2')
    end

--[[ TestLobbyTdc ]]--

