     "Looking to trade"
     "Looking to play"
 ]
-
-heroData = []
-lobbies =
+DOTA_LOBBIES =
     "-1": "Invalid"
     0: "Public matchmaking"
     1: "Practice"

    "Top tier 2"
    "Top tier 1"
]

module.exports = (robot) ->
    if not STEAM_API_KEY?
        return robot.logger.debug 'Missing STEAM_API_KEY in environment. Please set and try again.'

    fs.readFile 'data/heroes.bin', (err, data) ->
        return robot.logger.error if err
        heroData = msgpack.unpack data

    steamData = ->
        robot.brain.data.steam or= {}

    robot.respond /steam id( me)? (.*)/i, (msg) ->
        getSteamID msg, msg.match[2], (id) ->
            msg.match[2] += if msg.match[2].slice(-1) is "s" then "'" else "'s"
            msg.reply "#{msg.match[2]} Steam ID is: #{id}"

    robot.respond /steam status (.*)/i, (msg) ->
        summary = (steamID) ->
            steamRequest msg, "/ISteamUser/GetPlayerSummaries", steamids: steamID, (object) ->
                player = object.response.players[0]
                status = if player.communityvisibilitystate is 1 then 'Unavailable (Private)' else personaStates[player.personastate]
                lastOnline = moment.unix(player.lastlogoff).fromNow()
                msg.reply "#{msg.match[1]} belongs to #{player.personaname} who is currently #{status} and was last online #{lastOnline}."
            , 2

        if msg.match[1].match /\d{17}/
            summary msg.match[1]
        else
            getSteamID msg, msg.match[1], (steamID) ->
                summary steamID

    robot.respond /dota history (.*)/i, (msg) ->
        [command, value] = msg.match

        params =
            original: value
            account_id: value
            matches_requested: 5

        history = (params, type = 'Steam ID') ->
            steamRequest msg, "/IDOTA2Match_570/GetMatchHistory", params, (object) ->
                if object.result.status is 15
                    msg.reply "The #{type} you have entered (\"#{params.original}\") does not exist or it does not have match history enabled."
                    return
                else if object.result.num_results is 0
                    msg.reply "No game matches were found for the #{type}: #{params.original}."
                    return

                communityID = getCommunityID params.account_id

                for match in object.result.matches
                    hero = "N/A"
                    start = moment.unix(match.start_time).fromNow()

                    for player in match.players
                        if player.account_id is communityID
                            hero = getHero(player.hero_id).LocalizedName
                            break;

                    msg.send "Match ID: #{match.match_id} | Lobby: #{lobbies[match.lobby_type]} | Hero: #{hero} | #{start}"

        if value.match /\d{17}/
            history params
        else
            getSteamID msg, value, (id) ->
                params.account_id = id
                history params, 'profile URL'

    robot.respond /dota match (\d+)\s*(.*)?/i, (msg) ->
        steamRequest msg, "/IDOTA2Match_570/GetMatchDetails", match_id: msg.match[1], (object) ->
            match = object.result
            start = moment.unix(match.start_time).fromNow()
            duration = moment.duration(match.duration, 'seconds').minutes()
            firstBlood = moment.duration(match.first_blood_time, 'seconds').humanize()
            victor = if match.radiant_win then "Radiant" else "Dire"

            radiantTowers = getTowers(match.tower_status_radiant).join(', ') or 'None'
            direTowers = getTowers(match.tower_status_dire).join(', ') or 'None'

            msg.send "Match ID #{match.match_id} is a #{lobbies[match.lobby_type].toLowerCase()} game that took place #{start}. The #{victor} won the game in #{duration} minutes. First blood was drawn #{firstBlood} into the game."
            msg.send "Radiant towers remaining: #{radiantTowers} | Dire towers remaining: #{direTowers}"

            playerInfo = (communityID) ->
                for player in match.players
                    if player.account_id is communityID
                        faction = if player.player_slot > 4 then 'Dire' else 'Radiant'
                        msg.reply "#{getHero(player.hero_id).LocalizedName} (Lvl #{player.level}), #{faction} | KDA: #{player.kills}/#{player.deaths}/#{player.assists} | LH: #{player.last_hits} | GPM: #{player.gold_per_min} | XPM: #{player.xp_per_min}"
                        return
                msg.reply "The Steam ID you have entered (\"#{msg.match[1]}\") was not found in Match ID #{match.match_id}."

            if msg.match[2]?
                if msg.match[2].match /\d{17}/
                    playerInfo getCommunityID(msg.match[2])
                else
                    getSteamID msg, msg.match[2], (steamID) ->
                        playerInfo getCommunityID(steamID)

    getSteamID = (msg, customURL, handler) ->
        for steamID, user of steamData()
            return handler steamID if user.url is customURL

        steamRequest msg, "/ISteamUser/ResolveVanityURL", vanityurl: customURL, (object) ->
            if object.response.success is 42
                msg.reply "The custom URL you have entered (\"#{customURL}\") does not exist."
                return

            steamData()[object.response.steamid] or= {}
            steamData()[object.response.steamid].url = customURL

            handler object.response.steamid

    getCommunityID = (steamID) ->
        if steamData()[steamID]?.cID?
            return steamData()[steamID].cID

        # 64 -> 32
        buffer = new Buffer 8
        buffer.writeUInt64LE steamID, 0
        communityID = buffer.readUInt32LE 0

        steamData()[steamID] or= {}
        steamData()[steamID].cID = communityID

        communityID

getHero = (heroID) ->
    return hero for hero in heroData.Heroes when hero.Id is heroID

getTowers = (dec) ->
    for status, tower in "00000000000#{(+dec).toString(2)}".slice(-11).split('')
        if parseInt(status) then towers[tower] else continue

steamRequest = (msg, endpoint, params = {}, handler, version = 1) ->
    params.key = STEAM_API_KEY

    msg.http("http://api.steampowered.com#{endpoint}/v#{version}/")
        .query(params)
        .get() (err, res, body) ->
            if err or res.statusCode isnt 200
                err = "Bad request (invalid Steam web API key)" if res.statusCode is 400
                msg.reply "An error occurred while attempting to process your request."
                return robot.logger.error err

            handler JSON.parse(body)
# Description:
#   Steam Web API w/ Dota 2
#
# Dependencies:
#   "moment": "^2.8.1"
#   "msgpack": "^0.2.3"
#   "ref": "^0.3.2"
#
# Configuration:
#   STEAM_API_KEY
