# Path: invoker.py
# class ReplyObject:
#     """ Class for returning information from a command to the core program.
# 
#     Parameters used for creating this class defines the behaviour of the main
#     program when it comes across the reply object.
# 
#     Attributes:
#         text: str, the content of the reply.
#         samePlace: bool, if the response will always be in pm or where the command
#         was said.
#         ignoreEscaping: bool, default every reply is escaped to not allow
#         arbitrary commands to be executed through replies. Some commands require
#         to be able to use PS commands, which is when this should be overwritten.
#         ignoreBroadcastPermission: bool, ignore the global broadcast permission
#         for the reply if this is true.
#         gameCommand: bool, unused, pending removal.
#         canPmReply: bool, override the default request for users without broadcast
#         permission to pm the command and instead return the result of the action.
#         isException: bool, if a command throws an exception this will be true.
#     """
#     def __init__(self, res = '', reply = False, escape = False, broadcast = False, game = False, pmreply = False, ignoreml = False):
#         self.text = str(res)
#         self.samePlace = reply
#         self.ignoreEscaping = escape
#         self.ignoreBroadcastPermission = broadcast
#         self.ignoreMultiline = ignoreml
#         self.gameCommand = game
#         self.canPmReply = pmreply
#         self.isException = isinstance(res, Exception)
# 
#     def __eq__(self, other):
#         try:
#             return (self.text == other.text
#                 and self.samePlace == other.samePlace
#                 and self.ignoreEscaping == other.ignoreEscaping
#                 and self.ignoreBroadcastPermission == other.ignoreBroadcastPermission
#                 and self.ignoreMultiline == other.ignoreMultiline
#                 and self.gameCommand == other.gameCommand
#                 and self.canPmReply == other.canPmReply
#                 and self.isException == other.isException
#             )
#         except:
#             # This only happens if the other object isn't a matching object
#             return False
# 
#     def response(self, text):
#         self.text = text
#         return self
#     def extra(self, text):
#         self.text += text
#         return self
# 
# class Command:
#     """ Wrapper class that every command should use when being created.
# 
#     The default run method should never be called, and any instance of the
#     class should override this method on creation of the instance.
# 
#     Commands should also implement any private methods they may need for completion
# 
#     Attributes:
#         cmdTriggers: List, list of every trigger that should be used to invoke
#         this method.
#         altHtml: Bool, true if the command has alternate output if HTML is supported.
#     """
#     def __init__(self, triggers, nonAbsRun = None, html = False):
#         self.cmdTriggers = triggers
#         self.altHtml = html
#         self.hasBroadcastAlt = False
#         # This will hide the default run method if it is given on object creation
#         self.run = nonAbsRun if nonAbsRun else self.run
#     def run(self, robot, cmd, room, params, user):
#         """Abstract method for executing a command after it has been found. Each command
#         has to reimplement this function to work.
# 
#         Args:
#             robot: PokemonShowdownBot, the instance of PokemonShowdownBot that called this function.
#             cmd: string, the command that was send.
#             room: Room, the room object that the command was sent from.
#             params: string, additional paramters that the command may need.
#             user: User, the user object of the user who sent the command.
#         Returns:
#             ReplyObject.
#         Raises:
#             NotImplementedError if not implemented, otherwise unknown. """
#         raise NotImplementedError('Command#run method not implemented')


import json
import glob
import os
import yaml
import re
import requests
import textwrap
from collections import defaultdict
    from yaml import CLoader as Loader
    from yaml import Loader
from datetime import datetime
from random import randint
from invoker import ReplyObject, Command
    if not user.hasRank('%'): return reply.response('Permission denied. Room Driver (%) or higher')
    if not room.tour: return reply.response('No tournament found')
    room.tour.official = False

def resetofficials(bot, cmd, msg, user, room):
    reply = ReplyObject('', True, True)
    if not user.hasRank('@'): return reply.response('Permission denied. Room Mod (@) or higher')

    fileList = glob.glob('plugins/stats/{room}/*/official-rankings.yaml'.format(room=room.title))
    if not fileList:
        return reply.response('No official rankings to clear')
    try:
        for f in fileList:
            os.remove(f)
        return reply.response('Official rankings reset')
    except FileNotFoundError:
        return reply.response('Error while clearing official data')

# Exports
handlers = {
    'tournament': tourHandler,
    'queryresponse': queryresponse,
    'raw': rawmessage,
}

commands = [
    Command(['oldgentour'], oldgentour),
    Command(['tourhistory'], tourhistory),
    Command(['leaderboard', 'officialleaderboard'], getranking),
    Command(['excludetour'], excludetour),

# Path: invoker.py
# class ReplyObject:
#     """ Class for returning information from a command to the core program.
# 
#     Parameters used for creating this class defines the behaviour of the main
#     program when it comes across the reply object.
# 
#     Attributes:
#         text: str, the content of the reply.
#         samePlace: bool, if the response will always be in pm or where the command
#         was said.
#         ignoreEscaping: bool, default every reply is escaped to not allow
#         arbitrary commands to be executed through replies. Some commands require
#         to be able to use PS commands, which is when this should be overwritten.
#         ignoreBroadcastPermission: bool, ignore the global broadcast permission
#         for the reply if this is true.
#         gameCommand: bool, unused, pending removal.
#         canPmReply: bool, override the default request for users without broadcast
#         permission to pm the command and instead return the result of the action.
#         isException: bool, if a command throws an exception this will be true.
#     """
#     def __init__(self, res = '', reply = False, escape = False, broadcast = False, game = False, pmreply = False, ignoreml = False):
#         self.text = str(res)
#         self.samePlace = reply
#         self.ignoreEscaping = escape
#         self.ignoreBroadcastPermission = broadcast
#         self.ignoreMultiline = ignoreml
#         self.gameCommand = game
#         self.canPmReply = pmreply
#         self.isException = isinstance(res, Exception)
# 
#     def __eq__(self, other):
#         try:
#             return (self.text == other.text
#                 and self.samePlace == other.samePlace
#                 and self.ignoreEscaping == other.ignoreEscaping
#                 and self.ignoreBroadcastPermission == other.ignoreBroadcastPermission
#                 and self.ignoreMultiline == other.ignoreMultiline
#                 and self.gameCommand == other.gameCommand
#                 and self.canPmReply == other.canPmReply
#                 and self.isException == other.isException
#             )
#         except:
#             # This only happens if the other object isn't a matching object
#             return False
# 
#     def response(self, text):
#         self.text = text
#         return self
#     def extra(self, text):
#         self.text += text
#         return self
# 
# class Command:
#     """ Wrapper class that every command should use when being created.
# 
#     The default run method should never be called, and any instance of the
#     class should override this method on creation of the instance.
# 
#     Commands should also implement any private methods they may need for completion
# 
#     Attributes:
#         cmdTriggers: List, list of every trigger that should be used to invoke
#         this method.
#         altHtml: Bool, true if the command has alternate output if HTML is supported.
#     """
#     def __init__(self, triggers, nonAbsRun = None, html = False):
#         self.cmdTriggers = triggers
#         self.altHtml = html
#         self.hasBroadcastAlt = False
#         # This will hide the default run method if it is given on object creation
#         self.run = nonAbsRun if nonAbsRun else self.run
#     def run(self, robot, cmd, room, params, user):
#         """Abstract method for executing a command after it has been found. Each command
#         has to reimplement this function to work.
# 
#         Args:
#             robot: PokemonShowdownBot, the instance of PokemonShowdownBot that called this function.
#             cmd: string, the command that was send.
#             room: Room, the room object that the command was sent from.
#             params: string, additional paramters that the command may need.
#             user: User, the user object of the user who sent the command.
#         Returns:
#             ReplyObject.
#         Raises:
#             NotImplementedError if not implemented, otherwise unknown. """
#         raise NotImplementedError('Command#run method not implemented')


# Path: plugins/tournaments.py
import json
import glob
import os
import yaml
import re
import requests
import textwrap
from collections import defaultdict
    from yaml import CLoader as Loader
    from yaml import Loader
from datetime import datetime
from random import randint
from invoker import ReplyObject, Command

    if not user.hasRank('%'): return reply.response('Permission denied. Room Driver (%) or higher')
    if not room.tour: return reply.response('No tournament found')
    room.tour.official = False

def resetofficials(bot, cmd, msg, user, room):
    reply = ReplyObject('', True, True)
    if not user.hasRank('@'): return reply.response('Permission denied. Room Mod (@) or higher')

    fileList = glob.glob('plugins/stats/{room}/*/official-rankings.yaml'.format(room=room.title))
    if not fileList:
        return reply.response('No official rankings to clear')
    try:
        for f in fileList:
            os.remove(f)
        return reply.response('Official rankings reset')
    except FileNotFoundError:
        return reply.response('Error while clearing official data')

# Exports
handlers = {
    'tournament': tourHandler,
    'queryresponse': queryresponse,
    'raw': rawmessage,
}

commands = [
    Command(['oldgentour'], oldgentour),
    Command(['tourhistory'], tourhistory),
    Command(['leaderboard', 'officialleaderboard'], getranking),
    Command(['excludetour'], excludetour),

    Command(['resetofficials'], resetofficials)