#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2014 uralbash <root@uralbash.ru>
#
# Distributed under terms of the MIT license.

"""
Extension type for SQLAlchemy
"""
import os
import uuid
import logging

from sqlalchemy.types import CHAR, String, VARCHAR, TypeDecorator
from sqlalchemy.dialects.postgresql.base import UUID


class FileStore(TypeDecorator):
    impl = VARCHAR

    def __init__(self, path='', abspath='', *arg, **kw):
        TypeDecorator.__init__(self, *arg, **kw)
        self.path = path
        self.abspath = abspath

    def process_bind_param(self, value, dialect):
        if value is not None:
            if hasattr(value, 'filename'):
                return os.path.join(self.path, value.filename)
            if 'http://' in value or 'https://' in value:
                return value
            return os.path.join(self.path, value)

    def process_result_value(self, value, dialect):
        if value is not None:
            value = value
        return value

    def __repr__(self):
        return self.path


class GUID(TypeDecorator):

    """Platform-independent GUID type.

    Uses Postgresql's UUID type, otherwise uses
    CHAR(32), storing as stringified hex values.

    """
    impl = CHAR

    def load_dialect_impl(self, dialect):
        if dialect.name == 'postgresql':
            return dialect.type_descriptor(UUID())  # pragma: no cover
        else:
            return dialect.type_descriptor(CHAR(32))

    def process_bind_param(self, value, dialect):
        if value is None:
            return value
        elif dialect.name == 'postgresql':
            return str(value)  # pragma: no cover
        else:
            if not isinstance(value, uuid.UUID):
                return "%.32x" % uuid.UUID(value)
            else:
                # hexstring
                return "%.32x" % value

    def process_result_value(self, value, dialect):
        if value is None:
            return value
        else:
            return uuid.UUID(value)


class ChoiceType(TypeDecorator):

    """ Example:

.. code-block:: python
    :linenos:

    from sacrud.exttype import ChoiceType

    Base = declarative_base()

    REDIRECT_CHOICES = (
        ('OK (200)', '200'),
        ('Moved Permanently (301)', '301'),
        ('Moved Temporarily (302)', '302'),
    )

    class SuperChoiceModel(Base):
        ...
        redirect_type = Column(ChoiceType(choices=REDIRECT_CHOICES))
    """

    impl = String

    def __init__(self, choices=(), **kw):
        self.choices = choices
        super(ChoiceType, self).__init__(**kw)


class SlugType(TypeDecorator):

    impl = String

    def __init__(self, input_id="name", reflection=True, **kw):
        self.input_id = input_id
        self.reflection = reflection
        super(SlugType, self).__init__(**kw)

    def process_bind_param(self, value, dialect):
        if value == '/':
            return value
        try:
            from slugify import slugify
            return slugify(value)
        except ImportError:
            logging.warning("You must install python-slugify!!!")
            return value
