#       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 urllib import unquote
from webob import exc

from tg import expose, request, redirect
from ming.utils import LazyProperty

from allura.lib.security import require_access
from .base import BaseController


# text/html, script, flash, image/svg+xml, etc are NOT secure to display directly in the browser
SAFE_CONTENT_TYPES = (
    'image/png', 'image/x-png',
    'image/jpeg', 'image/pjpeg', 'image/jpg',
    'image/gif',
    'image/bmp',
    'image/tiff',
    'image/x-icon',
)


class AttachmentsController(BaseController):
    AttachmentControllerClass = None

    def __init__(self, artifact):
        self.artifact = artifact

    @expose()
    def _lookup(self, filename=None, *args):
        if filename:
            if not args:
                filename = request.path.rsplit('/', 1)[-1]
            filename = unquote(filename)
            return self.AttachmentControllerClass(filename, self.artifact), args
        else:
            raise exc.HTTPNotFound


class AttachmentController(BaseController):
    AttachmentClass = None
    edit_perm = 'edit'

    def _check_security(self):
        require_access(self.artifact, 'read')
        status = getattr(self.artifact, 'status', None)
        if status == 'pending':
            require_access(self.artifact, 'moderate')

    def __init__(self, filename, artifact):
        self.filename = filename
        self.artifact = artifact

    @LazyProperty
    def attachment(self):
        metadata = self.AttachmentClass.metadata_for(self.artifact)
        metadata['type'] = 'attachment'
        attachment = self.AttachmentClass.query.get(
            filename=self.filename, **metadata)
        if attachment is None:
            raise exc.HTTPNotFound
        return attachment

    @LazyProperty
    def thumbnail(self):
        metadata = self.AttachmentClass.metadata_for(self.artifact)
        metadata['type'] = 'thumbnail'
        attachment = self.AttachmentClass.query.get(
            filename=self.filename, **metadata)
        if attachment is None:
            raise exc.HTTPNotFound
        return attachment

    def handle_post(self, delete, **kw):
        require_access(self.artifact, self.edit_perm)
        if delete:
            self.attachment.delete()
            try:
                if self.thumbnail:
                    self.thumbnail.delete()
            except exc.HTTPNotFound:
                pass

    @expose()
    def index(self, delete=False, **kw):
        if request.method == 'POST':
            self.handle_post(delete, **kw)
            redirect(request.referer)
        if self.artifact.deleted:
            raise exc.HTTPNotFound
        embed = False
        if self.attachment.content_type and self.attachment.content_type in SAFE_CONTENT_TYPES:
            embed = True
        return self.attachment.serve(embed=embed)

    @expose()
    def thumb(self):
        if self.artifact.deleted:
            raise exc.HTTPNotFound
        return self.thumbnail.serve(embed=True)
