# This file is part of PRAW.
#
# PRAW is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# PRAW 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# PRAW.  If not, see <http://www.gnu.org/licenses/>.

"""
Python Reddit API Wrapper.

PRAW, an acronym for "Python Reddit API Wrapper", is a python package that
allows for simple access to reddit's API. PRAW aims to be as easy to use as
possible and is designed to follow all of reddit's API rules. You have to give
a useragent, everything else is handled by PRAW so you needn't worry about
violating them.

More information about PRAW can be found at https://github.com/praw-dev/praw
"""

from __future__ import print_function, unicode_literals

import json
import os
import platform
import re
import six
import sys
from praw import decorators, errors
from praw.handlers import DefaultHandler
from praw.helpers import normalize_url
from praw.internal import (_prepare_request, _raise_redirect_exceptions,
                           _raise_response_exceptions, _to_reddit_list)
from praw.settings import CONFIG
from requests import Session
from requests.compat import urljoin
from requests.utils import to_native_string
from requests import Request
# pylint: disable=F0401
from six.moves import html_entities, http_cookiejar
from six.moves.urllib.parse import parse_qs, urlparse, urlunparse
# pylint: enable=F0401
from update_checker import update_check
from warnings import warn_explicit


__version__ = '3.1.0'

if os.environ.get('SERVER_SOFTWARE') is not None:
    # Google App Engine information
    # https://developers.google.com/appengine/docs/python/
    PLATFORM_INFO = os.environ.get('SERVER_SOFTWARE')
else:
    # Standard platform information
    PLATFORM_INFO = platform.platform(True)

UA_STRING = '%%s PRAW/%s Python/%s %s' % (__version__,
                                          sys.version.split()[0],
                                          PLATFORM_INFO)

MIN_IMAGE_SIZE = 128
MAX_IMAGE_SIZE = 512000
JPEG_HEADER = b'\xff\xd8\xff'
PNG_HEADER = b'\x89\x50\x4e\x47\x0d\x0a\x1a\x0a'

# Compatibility
if six.PY3:
    CHR = chr
else:
    CHR = unichr  # NOQA


class Config(object):  # pylint: disable=R0903

    """A class containing the configuration for a reddit site."""

    API_PATHS
 = {'accept_mod_invite':   'api/accept_moderator_invite',
               
  'access_token_url':    'api/v1/access_token/',
                 'approve':             'api/approve/',
                 'authorize':           'api/v1/authorize/',
                 'banned':              'r/%s/about/banned/',
                 'blocked':             'prefs/blocked/',
                 'by_id':               'by_id/',
                 'captcha':             'captcha/',
                 'clearflairtemplates': 'api/clearflairtemplates/',
                 'comment':             'api/comment/',
                 'comment_replies':     'message/comments/',
                 'comments':            'comments/',
                 'compose':             'api/compose/',
                 'contest_mode':        'api/set_contest_mode/',
                 'contributors':        'r/%s/about/contributors/',
                 'controversial':       'controversial/',
                 'del':                 'api/del/',
                 'deleteflair':         'api/deleteflair',
                 'delete_redditor':     'api/delete_user',
                 'delete_sr_header':    'r/%s/api/delete_sr_header',
                 'delete_sr_image':     'r/%s/api/delete_sr_img',
                 'distinguish':         'api/distinguish/',
                 'domain':              'domain/%s/',
                 'duplicates':          'duplicates/%s/',
                 'edit':                'api/editusertext/',
                 'flair':               'api/flair/',
                 'flairconfig':         'api/flairconfig/',
                 'flaircsv':            'api/flaircsv/',
                 'flairlist':           'r/%s/api/flairlist/',
                 'flairselector':       'api/flairselector/',
                 'flairtemplate':       'api/flairtemplate/',
                 'friend':              'api/friend/',
                 'friends':             'prefs/friends/',
                 'gild_thing':          'api/v1/gold/gild/{fullname}/',
                 'gild_user':           'api/v1/gold/give/{username}/',
                 'help':                'help/',
                 'hide':                'api/hide/',
                 'ignore_reports':      'api/ignore_reports/',
                 'inbox':               'message/inbox/',
                 'info':                'api/info/',
                 'login':               'api/login/',
                 'me':                  'api/v1/me',
                 'mentions':            'message/mentions',
                 'message':             'message/messages/%s/',
                 'messages':            'message/messages/',
                 'moderators':          'r/%s/about/moderators/',
                 'modlog':              'r/%s/about/log/',
                 'modqueue':            'r/%s/about/modqueue/',
                 'mod_mail':            'r/%s/message/moderator/',
                 'morechildren':        'api/morechildren/',
                 'my_con_subreddits':   'subreddits/mine/contributor/',
                 'my_mod_subreddits':   'subreddits/mine/moderator/',
                 'my_multis':           'api/multi/mine/',
                 'my_subreddits':       'subreddits/mine/subscriber/',
                 'new':                 'new/',
                 'new_subreddits':      'subreddits/new/',
                 'marknsfw':            'api/marknsfw/',
                 'multireddit':         'user/%s/m/%s/',
                 'multireddit_add':     'api/multi/user/%s/m/%s/r/%s',
                 'multireddit_about':   'api/multi/user/%s/m/%s/',
                 'multireddit_copy':    'api/multi/copy/',
                 'multireddit_mine':    'me/m/%s/',
                 'multireddit_rename':  'api/multi/rename/',
                 'multireddit_user':    'api/multi/user/%s/',
                 'popular_subreddits':  'subreddits/popular/',
                 'post_replies':        'message/selfreply/',
                 'read_message':        'api/read_message/',
                 'reddit_url':          '/',
                 'register':            'api/register/',
                 'remove':              'api/remove/',
                 'report':              'api/report/',
                 'reports':             'r/%s/about/reports/',
                 'rising':              'rising/',
                 'save':                'api/save/',
                 'saved':               'saved/',
                 'search':              'r/%s/search/',
                 'search_reddit_names': 'api/search_reddit_names/',
                 'select_flair':        'api/selectflair/',
                 'sent':                'message/sent/',
                 'sticky':              'r/%s/about/sticky/',
                 'sticky_submission':   'api/set_subreddit_sticky/',
                 'site_admin':          'api/site_admin/',
                 'spam':                'r/%s/about/spam/',
                 'stylesheet':          'r/%s/about/stylesheet/',
                 'submit':              'api/submit/',
                 'sub_comments_gilded': 'r/%s/comments/gilded/',
                 'sub_recommendations': 'api/recommend/sr/{0}',
                 'subreddit':           'r/%s/',
                 'subreddit_about':     'r/%s/about/',
       