#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you under the Apache License, Version 2.0 (the
#       "License"); you may not use this file except in compliance
#       with the License.  You may obtain a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#       Unless required by applicable law or agreed to in writing,
#       software distributed under the License is distributed on an
#       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
#       KIND, either express or implied.  See the License for the
#       specific language governing permissions and limitations
#       under the License.

from ming.base import Object
from ming import schema as S

EVERYONE, ALL_PERMISSIONS = None, '*'


class MarkdownCache(S.Object):

    def __init__(self, **kw):
        super(MarkdownCache, self).__init__(
            fields=dict(
                md5=S.String(),
                html=S.String(),
                render_time=S.Float()),
            **kw)


class ACE(S.Object):
    '''
    Access Control Entry

    :var access: either ``ACE.ALLOW`` or ``ACE.DENY``
    :var str reason: optional, user-entered text
    :var role_id: _id for a :class:`~allura.model.auth.ProjectRole`
    :var str permission: e.g. 'read', 'create', etc
    '''

    ALLOW, DENY = 'ALLOW', 'DENY'

    def __init__(self, permissions, **kwargs):
        if permissions is None:
            permission = S.String()
        else:
            permission = S.OneOf('*', *permissions)
        super(ACE, self).__init__(
            fields=dict(
                access=S.OneOf(self.ALLOW, self.DENY),
                reason=S.String(),
                role_id=S.ObjectId(),
                permission=permission),
            **kwargs)

    @classmethod
    def allow(cls, role_id, permission, reason=None):
        return Object(
            access=cls.ALLOW,
            reason=reason,
            role_id=role_id,
            permission=permission)

    @classmethod
    def deny(cls, role_id, permission, reason=None):
        ace = Object(
            access=cls.DENY,
            reason=reason,
            role_id=role_id,
            permission=permission)
        return ace

    @classmethod
    def match(cls, ace, role_id, permission):
        return (
            ace.role_id in (role_id, EVERYONE)
            and ace.permission in (permission, ALL_PERMISSIONS))


class ACL(S.Array):
    '''
    Access Control List.  Is an array of :class:`ACE`
    '''

    def __init__(self, permissions=None, **kwargs):
        super(ACL, self).__init__(
            field_type=ACE(permissions), **kwargs)

    @classmethod
    def contains(cls, ace, acl):
        """Test membership of ace in acl ignoring ace.reason field.

        Return actual ACE with reason filled if ace is found in acl, None otherwise

        e.g. `ACL.contains(ace, acl)` will return `{role_id=ObjectId(...), permission='read', access='DENY', reason='Spammer'}`
        with following vars:

        ace = M.ACE.deny(role_id, 'read')  # reason = None
        acl = [{role_id=ObjectId(...), permission='read', access='DENY', reason='Spammer'}]
        """
        def clear_reason(ace):
            return Object(access=ace.access, role_id=ace.role_id, permission=ace.permission)

        ace_without_reason = clear_reason(ace)
        for a in acl:
            if clear_reason(a) == ace_without_reason:
                return a

DENY_ALL = ACE.deny(EVERYONE, ALL_PERMISSIONS)
