# Copyright (C) 2014 Okami, <EMAIL>

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# 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 General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

import base64
import copy

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.urls import reverse
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import RedirectView, View
from django.utils.decorators import method_decorator

from radicale import Application


class ApplicationResponse(HttpResponse):
    def start_response(self, status, headers):
        self.status_code = int(status.split(' ')[0])
        if self.status_code == 207:
            self.reason_phrase = 'Multi-Status'
        for k, v in dict(headers).items():
            self[k] = v


class DjRadicaleView(Application, View):
    http_method_names = [
        'delete',
        'get',
        'head',
        'mkcalendar',
        'mkcol',
        'move',
        'options',
        'propfind',
        'proppatch',
        'put',
        'report',
    ]

    def __init__(self, **kwargs):
        super(DjRadicaleView, self).__init__()
        super(View, self).__init__(**kwargs)

    def do_HEAD(self, environ, read_collections, write_collections, content,
                user):
        """Manage HEAD request."""
        status, headers, answer = self.do_GET(
            environ, read_collections, write_collections, content, user)
        return status, headers, None

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        if not request.method.lower() in self.http_method_names:
            return self.http_method_not_allowed(request, *args, **kwargs)
        response = ApplicationResponse()
        answer = self(request.META, response.start_response)
        for i in answer:
            response.write(i)
        return response


class WellKnownView(DjRadicaleView):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        # do not authentificate yet, just get the username
        if 'HTTP_AUTHORIZATION' in self.request.META:
            auth = request.META['HTTP_AUTHORIZATION'].split()
            if len(auth) == 2:
                if auth[0].lower() == 'basic':
                    user, password = base64.b64decode(
                        auth[1]).decode().split(':')
                    if kwargs.get('type') == 'carddav':
                        url = '%s/addressbook.vcf/' % user
                    else:
                        url = '%s/calendar.ics/' % user
                    request.META['PATH_INFO'] = reverse(
                        'djradicale:application', kwargs={'url': url})
        return super().dispatch(request, *args, **kwargs)
