import json
import re

from django.utils.safestring import mark_safe
from rest_framework import serializers
from rest_framework.throttling import UserRateThrottle


class FailSafeJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        try:
            return super(FailSafeJSONEncoder, self).default(obj)
        except Exception:
            return str(obj)


def safe_json_dumps(data, **kwargs):
    return json.dumps(data, cls=FailSafeJSONEncoder, **kwargs)


class HourUserRateThrottle(UserRateThrottle):
    scope = "hour-throttle"


class DayUserRateThrottle(UserRateThrottle):
    scope = "day-throttle"


def find_first(iterable, pred=None, default=None):
    return next(filter(pred, iterable), default)


def find_first_index(iterable, pred, default=None):
    return next((i for i, x in enumerate(iterable) if pred(x)), default)


def replace_whitespace(text, replacement=" "):
    return re.sub(r"\s+", replacement, text).strip()


def get_django_content_type(obj):
    return obj._meta.app_label + "." + type(obj).__name__


class StringIDField(serializers.Field):
    def to_representation(self, value):
        return str(value)


def pretty_print_json(json_string):
    try:
        parsed = json_string
        if isinstance(json_string, str):
            parsed = json.loads(json_string)
        return mark_safe(
            "<pre>{}</pre>".format(json.dumps(parsed, indent=4, sort_keys=True))
        )
    # pylint: disable=broad-except
    except Exception:
        return json_string
