# ==============================================================================
# Copyright (C) 2019 - Philip Paquette, Steven Bocco
#
#  This program is free software: you can redistribute it and/or modify it under
#  the terms of the GNU Affero General Public License as published by the Free
#  Software Foundation, either version 3 of the License, or (at your option) any
#  later version.
#
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#  FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
#  details.
#
#  You should have received a copy of the GNU Affero General Public License along
#  with this program.  If not, see <https://www.gnu.org/licenses/>.
# ==============================================================================
""" Some strings frequently used (to help prevent typos). """

ABBREV = 'abbrev'
ACTIVE = 'active'
ADJUST = 'adjust'
ADM_MESSAGE = 'adm_message'
ADMIN = 'admin'
ADMINISTRATORS = 'administrators'
ALL_POSSIBLE_ORDERS = 'all_possible_orders'
ALLOCATE_COUNTRIES_RANDOMLY = 'allocate_countries_randomly'
ALLOW_MULTIPLE_COUNTRIES_PER_PLAYER = 'allow_multiple_countries_per_player'
ALLOW_NEW_PLAYERS_AFTER_START = 'allow_new_players_after_start'
ALLOW_OBSERVATIONS = 'allow_observations'
ALLOW_REGISTRATIONS = 'allow_registrations'
ALLOWED_VOTERS = 'allowed_voters'
ALWAYS_OMNISCIENT = 'always_omniscient'
AUTHENTICATION_TYPE = 'authentication_type'
AVAILABLE_MAPS = 'available_maps'
BACKUP_DELAY_SECONDS = 'backup_delay_seconds'
BODY = 'body'
BUFFER_SIZE = 'buffer_size'
CANCELED = 'canceled'
CENTERS = 'centers'
CHANNEL = 'channel'
CIVIL_DISORDER = 'civil_disorder'
CLEAR_INVALID_STATE_HISTORY = 'clear_invalid_state_history'
CLIENT_NAME = 'client_name'
CLIENT_VERSION = 'client_version'
COMPLETED = 'completed'
CONTENT = 'content'
CONTROLLED_POWERS = 'controlled_powers'
CONTROLLER = 'controller'
COUNT_EXPECTED = 'count_expected'
COUNT_VOTED = 'count_voted'
CURRENT_ORDER = 'current_order'
CURRENT_PHASE = 'current_phase'
CURRENT_PHASE_DATA = 'current_phase_data'
CURRENT_STATE = 'current_state'
CURRENT_TURN = 'current_turn'
DATA = 'data'
DEADLINE = 'deadline'
DEMOTE = 'demote'
DESC = 'desc'
DESIRED_COUNTRIES = 'desired_countries'
DUMMY = 'dummy'
DUMMY_PLAYER = 'dummy_player'
DUMMY_POWERS = 'dummy_powers'
ERROR = 'error'
ERROR_TYPE = 'error_type'
FOR_OMNISCIENCE = 'for_omniscience'
FORCED = 'forced'
FORCED_ORDERS = 'forced_orders'
FORCED_WAIT_FLAG = 'forced_wait_flag'
FORMING = 'forming'
FROM_PHASE = 'from_phase'
FROM_TIMESTAMP = 'from_timestamp'
GAME = 'game'
GAME_ID = 'game_id'
GAME_PHASE = 'game_phase'
GAME_ROLE = 'game_role'
GAME_STARTED = 'game_started'
GAMES = 'games'
GLOBAL_MESSAGE_HISTORY = 'global_message_history'
GRADE = 'grade'
GRADE_UPDATE = 'grade_update'
HASHED = 'hashed'
HOMES = 'homes'
INCLUDE_PROTECTED = 'include_protected'
INFLUENCE = 'influence'
INITIAL_STATE = 'initial_state'
IS_DUMMY = 'is_dummy'
KICK_PLAYER = 'kick_player'
MAP_NAME = 'map_name'
MAP_POWERS = 'map_powers'
MAPS = 'maps'
MAPS_MTIME = 'maps_mtime'
MASTER_TYPE = 'master_type'
MAX_GAMES = 'max_games'
MESSAGE = 'message'
MESSAGE_BYTES = 'message_bytes'
MESSAGE_HISTORY = 'message_history'
MESSAGES = 'messages'
META_RULES = 'meta_rules'
MODERATOR = 'moderator'
MODERATOR_USERNAMES = 'moderator_usernames'
MODERATORS = 'moderators'
N_CONTROLS = 'n_controls'
N_PLAYERS = 'n_players'
NAME = 'name'
NEUTRAL = 'neutral'
NO = 'no'
NO_RULES = 'no_rules'
NO_WAIT = 'no_wait'
NOTE = 'note'
NOTIFICATION = 'notification'
NOTIFICATION_ID = 'notification_id'
OBSERVER = 'observer'
OBSERVER_LEVEL = 'observer_level'
DAIDE_PORT = 'daide_port'
OBSERVER_NAME = 'observer_name'
OBSERVER_TYPE = 'observer_type'
OK = 'ok'
OMNISCIENT = 'omniscient'
OMNISCIENT_TYPE = 'omniscient_type'
OMNISCIENT_USERNAMES = 'omniscient_usernames'
ORDER = 'order'
ORDER_HISTORY = 'order_history'
ORDER_IS_SET = 'order_is_set'
ORDER_STATUS = 'order_status'
ORDERABLE_LOCATIONS = 'orderable_locations'
ORDERS = 'orders'
ORDERS_FINALIZED = 'orders_finalized'
ORDERS_STATUSES = 'orders_statuses'
OTHER_PLAYERS = 'other_players'
OUTCOME = 'outcome'
PARAMETERS = 'parameters'
PASSCODE = 'passcode'
PASSWORD = 'password'
PASSWORD_HASH = 'password_hash'
PAUSED = 'paused'
PHASE = 'phase'
PHASE_ABBR = 'phase_abbr'
PHASE_DATA = 'phase_data'
PHASE_DATA_TYPE = 'phase_data_type'
PING_SECONDS = 'ping_seconds'
PLAYER_ID = 'player_id'
PLAYERS = 'players'
POSSIBLE_ORDERS = 'possible_orders'
POWER = 'power'
POWER_FROM = 'power_from'
POWER_MESSAGE_HISTORY = 'power_message_history'
POWER_NAME = 'power_name'
POWER_NAMES = 'power_names'
POWER_NAMES_AGAINST = 'power_names_against'
POWER_NAMES_IN_FAVOUR = 'power_names_in_favour'
POWER_NAMES_NEUTRAL = 'power_names_neutral'
POWER_TO = 'power_to'
POWERS = 'powers'
POWERS_KICKED = 'powers_kicked'
PREVIOUS_PHASE = 'previous_phase'
PREVIOUS_PHASE_DATA = 'previous_phase_data'
PREVIOUS_STATE = 'previous_state'
PROMOTE = 'promote'
PROPOSAL = 'proposal'
RE_SENT = 're_sent'
REASON = 'reason'
RECIPIENT = 'recipient'
RECIPIENT_TOKEN = 'recipient_token'
REGISTER = 'register'
REGISTRATION_PASSWORD = 'registration_password'
REMOVE_CANCELED_GAMES = 'remove_canceled_games'
REMOVE_ENDED_GAMES = 'remove_ended_games'
REQUEST = 'request'
REQUEST_ID = 'request_id'
RESPONSE_BYTES = 'response_bytes'
RESULT = 'result'
RESULT_HISTORY = 'result_history'
RESULTS = 'results'
RETREATS = 'retreats'
ROLE = 'role'
RULES = 'rules'
SECONDS = 'seconds'
SENDER = 'sender'
SERVER_TYPE = 'server_type'
SET_ORDER = 'set_order'
SETTINGS = 'settings'
START_AUTO = 'start_auto'
START_MASTER = 'start_master'
START_MODE = 'start_mode'
STATE = 'state'
STATE_HISTORY = 'state_history'
STATE_TYPE = 'state_type'
STATES = 'states'
STATUS = 'status'
SUPPLY_CENTERS = 'supply_centers'
TIME_SENT = 'time_sent'
TIMESTAMP = 'timestamp'
TIMESTAMP_CREATED = 'timestamp_created'
TIMESTAMP_SAVED = 'timestamp_saved'
TIMESTAMP_SYNC = 'timestamp_sync'
TIMESTAMPS = 'timestamps'
TO_PHASE = 'to_phase'
TO_TIMESTAMP = 'to_timestamp'
TOKEN = 'token'
TOKEN_TIMESTAMP = 'token_timestamp'
TOKEN_TO_USERNAME = 'token_to_username'
TOKENS = 'tokens'
TURN = 'turn'
TURN_HISTORY = 'turn_history'
UNDECIDED_PLAYER_MODE = 'undecided_player_mode'
UNITS = 'units'
USERNAME = 'username'
USERNAME_TO_TOKENS = 'username_to_tokens'
USERS = 'users'
VICTORY = 'victory'
VOTE = 'vote'
VOTE_ID = 'vote_id'
VOTE_IS_FORCED = 'vote_is_forced'
VOTES = 'votes'
WAIT = 'wait'
WIN = 'win'
WINNERS = 'winners'
WINTER_UNDECIDED_PLAYER_MODE = 'winter_undecided_player_mode'
YES = 'yes'
ZOBRIST_HASH = 'zobrist_hash'

# Special name sets.
ALL_GAME_STATUSES = (FORMING, ACTIVE, PAUSED, COMPLETED, CANCELED)
ALL_GRADE_UPDATES = {PROMOTE, DEMOTE}
ALL_GRADES = {OMNISCIENT, ADMIN, MODERATOR}
ALL_COMM_LEVELS = {CHANNEL, GAME}
ALL_VOTE_DECISIONS = {YES, NO, NEUTRAL}
ALL_ROLE_TYPES = {OBSERVER_TYPE, OMNISCIENT_TYPE, SERVER_TYPE}
ALL_STATE_TYPES = {STATE_HISTORY, STATE, PHASE}

def role_is_special(role):
    """ Return True if role is a special role (observer or omniscient). """
    return role in {OBSERVER_TYPE, OMNISCIENT_TYPE}

def switch_special_role(role):
    """ Return opposite special role of given special role:

            - observer role if omniscient role is given
            - omniscient role if observer role is given
    """
    if role == OBSERVER_TYPE:
        return OMNISCIENT_TYPE
    if role == OMNISCIENT_TYPE:
        return OBSERVER_TYPE
    raise ValueError('Unknown special role %s' % role)