# -*- encoding: utf-8 -*-
import os

from django.views.decorators.csrf import csrf_exempt
from django.core.urlresolvers import reverse
from django.core.files.storage import DefaultStorage
from django.core.files import File
from django.http import HttpResponse, Http404
from django.utils import simplejson
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _

from .models import FileTypeAttachedFileKind

def get_paths_for_id(upload_id):
    storage = DefaultStorage()
    path = os.path.join('upload', upload_id)
    if not storage.exists(path):
        return []
    return list(storage.listdir(path)[1])

def get_files_for_id(upload_id):
    storage = DefaultStorage()
    path = os.path.join('upload', upload_id)
    if not storage.exists(path):
        return
    for filepath in storage.listdir(path)[1]:
        name = os.path.basename(filepath)
        yield storage.open(os.path.join(path, name))

def get_data_for_id(upload_id):
    for file_object in get_files_for_id(upload_id):
        name = os.path.basename(file_object.name)
        url = reverse('uploaded', args=[upload_id, name])
        yield { 'name': name, 'size': file_object.size, 'url': url,
                'delete_url': url, 'delete_type': 'DELETE' }

def response_mimetype(request):
    if "application/json" in request.META['HTTP_ACCEPT']:
        return "application/json"
    else:
        return "text/plain"

class JSONResponse(HttpResponse):
    """JSON response class."""
    def __init__(self,obj='',json_opts={},mimetype="application/json",*args,**kwargs):
        content = simplejson.dumps(obj,**json_opts)
        super(JSONResponse,self).__init__(content,mimetype,*args,**kwargs)




@csrf_exempt
def upload(request, transaction_id, file_kind=None):
    # do not store files in memory, use the disk
    storage = DefaultStorage()
    max_filename_length = 256
    max_files = 0
    try:
        max_filename_length = int(request.GET.get('max_filename_length'))
    except (ValueError, TypeError):
        pass
    try:
        max_files = int(request.GET.get('cardinality'))
    except (ValueError, TypeError):
        pass
    if file_kind:
        file_kind = get_object_or_404(FileTypeAttachedFileKind, id=file_kind)
    url = reverse('upload', kwargs={'transaction_id': transaction_id})
    if request.method == 'POST' and request.FILES is not None:
        data = []
        for uploaded_file in request.FILES.values():
            if file_kind:
                if not file_kind.match_file(uploaded_file):
                    message = _('invalid file type, check required '
                            'file types for this field')
                    data.append({'name': uploaded_file.name, 'error': unicode(message) })
                    continue
                uploaded_file.open()
            if len(uploaded_file.name) > max_filename_length:
                message = _('filename too long, only %d characters allowed') % \
                        max_filename_length
                data.append({'name': uploaded_file.name, 'error': unicode(message) })
                continue
            if max_files:
                count = len(get_paths_for_id(transaction_id))
                if count >= max_files:
                    message = _('too much file attached, delete to add a new one')
                    data.append({'name': uploaded_file.name, 'error': unicode(message) })
                    continue
            path = os.path.join('upload', str(transaction_id), uploaded_file.name)
            filename = storage.save(path, uploaded_file)
            url = '%s%s' % (url, os.path.basename(filename))
            data.append({'name': uploaded_file.name, 'size':
                uploaded_file.size, 'url': url, 'delete_url': url,
                'delete_type': "DELETE"})
        response = JSONResponse(data, {}, response_mimetype(request))
        response['Content-Disposition'] = 'inline; filename=files.json'
        return response
    else:
        data = list(get_data_for_id(transaction_id))
        response = JSONResponse(data, {}, response_mimetype(request))
        response['Content-Disposition'] = 'inline; filename=files.json'
        return response

def file_response(file_object):
    if not isinstance(file_object, File):
        file_object = File(file_object)
    response = HttpResponse(file_object.chunks(), mimetype='application/octet-stream')
    response['Content-disposition'] = 'attachment'
    return response

@csrf_exempt
def upload_file(request, transaction_id, filename):
    storage = DefaultStorage()
    path = os.path.join('upload', transaction_id, filename)
    if request.method == 'DELETE':
        storage.delete(path)
        response = JSONResponse(True, {}, response_mimetype(request))
        response['Content-Disposition'] = 'inline; filename=files.json'
        return response
    if not storage.exists(path):
        raise Http404
    return file_response(storage.open(path))
