# copyright 2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr -- mailto:contact@logilab.fr
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation, either version 2.1 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 Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""cubicweb-skos schema"""

from yams.buildobjs import (EntityType, RelationDefinition, ComputedRelation,
                            String, RichString)

from cubicweb.schema import RQLConstraint, RRQLExpression

_ = unicode


class ConceptScheme(EntityType):
    """Vocabulary made of concepts"""
    title = String(unique=True, fulltextindexed=True)
    description = RichString(fulltextindexed=True)


class Concept(EntityType):
    """Unit of thought: idea, meaning, or (category of) object(s) and event(s)"""
    # URI of the concept is stored in the standard cwuri attribute
    definition = RichString(fulltextindexed=True)
    example = RichString(fulltextindexed=True)


class Label(EntityType):
    """Expression used to refer to a concept in natural language"""
    label = String(required=True, fulltextindexed=True)
    kind = String(required=True, internationalizable=True,
                  vocabulary=[_('preferred'), _('alternative'), _('hidden')],
                  default=u'preferred')
    language_code = String(maxsize=5,
                           description=_('language code, e.g. "en" or "fr-fr"'))


class in_scheme(RelationDefinition):
    __permissions__ = {
        'read': ('managers', 'users', 'guests'),
        'delete': (RRQLExpression('O cw_source SO, SO name = "system"'), ),
        'add': (RRQLExpression('O cw_source SO, SO name = "system"'), ),
    }
    subject = 'Concept'
    object = 'ConceptScheme'
    cardinality = '+*'
    composite = 'object'
    description = _('scheme the concept has been attached to')


class label_of(RelationDefinition):
    subject = 'Label'
    object = 'Concept'
    cardinality = '1+'
    inlined = True
    composite = 'object'
    description = _('concept label')
    fulltext_container = 'object'


class preferred_label(ComputedRelation):
    rule = 'O label_of S, O kind "preferred"'


class alternative_label(ComputedRelation):
    rule = 'O label_of S, O kind "alternative"'


class hidden_label(ComputedRelation):
    rule = 'O label_of S, O kind "hidden"'


class broader_concept(RelationDefinition):
    subject = 'Concept'
    object = 'Concept'
    cardinality = '**'
    description = _('more general concept')
    constraints = [RQLConstraint('S in_scheme CS, O in_scheme CS')]


class narrower_concept(ComputedRelation):
    rule = 'O broader_concept S'


class related_concept(RelationDefinition):
    subject = 'Concept'
    object = 'Concept'
    description = _('related concept')
    symmetric = True
    constraints = [RQLConstraint('S in_scheme CS, O in_scheme CS')]


class exact_match(RelationDefinition):
    subject = 'Concept'
    object = ('Concept', 'ExternalUri')
    description = _('equivalent concept in another vocabulary')
    symmetric = True


class close_match(RelationDefinition):
    subject = 'Concept'
    object = ('Concept', 'ExternalUri')
    description = _('close concept in another vocabulary')


class SKOSSource(EntityType):
    __permissions__ = {
        'read': ('managers', 'users', 'guests'),
        'add': ('managers', ),
        'update': ('managers', ),
        'delete': ('managers', ),
    }
    # description are the same as for CWSource attributes hence shouldn't be marked for translation
    # here
    name = String(required=True, unique=True, maxsize=128,
                  description=_('name of the source'))
    url = String(description=_('URLs from which content will be imported. '
                               'You can put one url per line'))


class through_cw_source(RelationDefinition):
    __permissions__ = {'read': ('managers', 'users'),
                       'add': (),
                       'delete': ()}
    subject = 'SKOSSource'
    object = 'CWSource'
    cardinality = '1*'
    composite = 'subject'
    inlined = True
