# -*- coding: utf-8 -*-

import re
import httplib as http

import pymongo
from modularodm.exceptions import ValidationValueError

from framework.exceptions import HTTPError

# MongoDB forbids field names that begin with "$" or contain ".". These
# utilities map to and from Mongo field names.

mongo_map = {
    '.': '__!dot!__',
    '$': '__!dollar!__',
}


def to_mongo(item):
    for key, value in mongo_map.items():
        item = item.replace(key, value)
    return item


def to_mongo_key(item):
    return to_mongo(item).strip().lower()


def from_mongo(item):
    for key, value in mongo_map.items():
        item = item.replace(value, key)
    return item


sanitize_pattern = re.compile(r'<\/?[^>]+>')
def sanitized(value):
    if value != sanitize_pattern.sub('', value):
        raise ValidationValueError('Unsanitary string')


def unique_on(*groups):
    """Decorator for subclasses of `StoredObject`. Add a unique index on each
    group of keys provided.

    :param *groups: List of lists of keys to be indexed
    """
    def wrapper(cls):
        cls.__indices__ = getattr(cls, '__indices__', [])
        cls.__indices__.extend([
            {
                'key_or_list': [
                    (key, pymongo.ASCENDING)
                    for key in group
                ],
                'unique': True,
            }
            for group in groups
        ])
        return cls
    return wrapper


def get_or_http_error(Model, pk, allow_deleted=False):
    instance = Model.load(pk)
    if not allow_deleted and getattr(instance, 'is_deleted', False):
        raise HTTPError(http.GONE, data=dict(
            message_long="This resource has been deleted"
        ))
    if not instance:
        raise HTTPError(http.NOT_FOUND, data=dict(
            message_long="No resource with that primary key could be found"
        ))
    else:
        return instance
