# -*- coding: utf-8 -*-
# courses.views

import re
import os
import mimetypes
import urllib.parse
from pathlib import Path
from shutil import copyfile
import io
import importlib

from django.shortcuts import render
from django.http import Http404, HttpResponse, HttpResponseRedirect
from wsgiref.util import FileWrapper

from courses.models import CourseSite, SecureCourseFile
from courses.forms import LoadScheduleForm
from courses.script import Scripter

from djphys.epoch import Epoch
from djphys.funcs import get_epoch
from djphys.models import Course
from people.funcs import is_faculty

if str(Path(__file__)).startswith('/Users'):
    BASE = Path('/Users/saeta/Documents/Courses')
else:
    BASE = Path('/home/saeta/Documents/courses')


def course_defaults(request, order_field=""):
    dic = {'request': request, }
    if not order_field:
        m = re.search(r'/c/([^/]*)/', request.path)
        order_field = m.group(1)

    dic['order_field'] = order_field
    dic['course'] = CourseSite.objects.get(course__order_field=order_field)
    dic['epoch'] = Epoch().deserialize(request.session['epoch'])
    dic['calendar'] = dic['course'].calendar(request)
    dic['course_rec'] = dic['course'].course_record(dic['epoch'])
    dic['request'] = request
    dic['logo'] = f"img/{order_field}-logo.gif"
    if is_faculty(request.user):
        dic['loadform'] = LoadScheduleForm()
    return dic


def dispatch(request, order_field, command=""):
    dic = course_defaults(request, order_field)

    # I now expect path in {home | download | load | pages | search | project}
    # some of these will be in this file; others will be in the order_field
    # subfolder

    if not command:
        command = 'home'

    if command in ('home', 'download', 'load'):
        mod = importlib.import_module(
            '..views', package=f'courses.{order_field}')
    else:
        mod = importlib.import_module(
            '..views', package=f'courses.{order_field}.views')
    f = getattr(mod, command)
    response = f(request, dic)
    #response = eval(order_field + "." + command + '(request, dic)')
    return response


def r2r(request, template, dic={}):
    # We should be able to figure out from the URL what CourseSite is
    # implicated and look up its logo, to inject in the dictionary
    m = re.search('/c/([^/]*)/', request.path)
    if m:
        try:
            course = Course.objects.get(order_field=m.group(1))
            logo = CourseSite.objects.get(course=course).logo
            if logo:
                dic['logo'] = logo
        except:
            pass
    if request.user.is_authenticated:
        dic['user'] = request.user
    return render(request, template, dic)


def home(request, dic):
    return r2r(request, f'courses/{dic["order_field"]}home.html', dic)


def mathematica(request):
    return r2r(request, 'courses/mathematica.html')


def load(request, dic):
    year = dic['epoch'].year
    ofield = dic['order_field']
    fname = BASE / ofield / f"{year}" / f"{ofield}-{year}.txt"
    sc = Scripter.load(fname)
    return HttpResponseRedirect(f'/c/{ofield}/')


def load_schedule(request):
    if request.method == 'POST':
        form = LoadScheduleForm(request.POST, request.FILES)
        if form.is_valid():
            source = form.cleaned_data['source']
            from courses.script import Scripter
            sc = Scripter.load(source)
            return HttpResponseRedirect(sc.url)
    else:
        from courses.p151.views import load
        return load(request)
    return home(request)


def download(request, dic):
    # dic = p151defaults(request)
    year = dic['epoch'].year
    ofield = dic['course'].course.order_field

    fname = BASE / ofield / f"{year}" / f"{ofield}-{year}.txt"
    l = request.GET.get('local', ['1'])[0]
    local = int(l) > 0

    if local:
        if fname.exists():
            # make a backup
            dest = fname.with_suffix('.bak')
            copyfile(fname, dest)
            print(f"Backed up to {dest.absolute()}")
        sc = Scripter(dic['course_rec'], filename=fname)
        return HttpResponseRedirect(sc.url)
    # We'll be returning a file
    f = io.StringIO()
    sc = Scripter(dic['course_rec'], filename=f)
    f.seek(0, io.SEEK_END)
    txt = bytes(f.getvalue(), 'utf-8')
    response = HttpResponse(txt)
    response['Content-Disposition'] = "attachment; filename=%s" % fname.name
    response['Content-Length'] = len(txt)
    return response


def xsendfile(request, fullpath):  # , document_root):
    # print( "xsendfile for %s @ %s" % (path, document_root) )
    # We need to deal with permission stuff here
    # That means we need to identify the data base object that corresponds to this path
    # Look for this filename in the SecureDocuments list
    # We should urllib.parse.unquote the filename
    from django.conf import settings
    document_root = settings.PRIVATE_ROOT
    dpath = urllib.parse.unquote(fullpath)
    print(dpath)
    try:
        print("Looking for a document with path {0}".format(dpath))
        doc = SecureCourseFile.objects.get(document=dpath)
        if not doc.has_access(request):
            from django.core.exceptions import PermissionDenied
            raise PermissionDenied()
    except:
        raise Http404()

    full_path = os.path.join(document_root, dpath)
    contentType = mimetypes.guess_type(full_path)[0]
    if contentType == None:
        ext = os.path.splitext(full_path)[1]
        if ext in ('.ipynb', '.pdf'):
            contentType = 'application/force-download'
    if settings.DEBUG:
        wrapper = FileWrapper(open(full_path, "rb"))
        if contentType == "image/jpeg":
            response = HttpResponse(wrapper, content_type=contentType)
        else:
            response = HttpResponse(
                wrapper, content_type="application/force-download")
            response['Content-Disposition'] = "attachment; filename=" + dpath
        response['Content-Length'] = os.path.getsize(full_path)
        return response

    try:
        #print("initiating X-Sendfile")
        response = HttpResponse()  # content_type=contentType)
        response['Content-Type'] = contentType # ''
        u = urllib.parse.quote(full_path.encode('utf-8'))
        response['X-Sendfile'] = u  # full_path.encode('utf-8') # u
        #print(( "I'm referring to '%s'" % (response['X-Sendfile'])))
    except:
        raise Http404
    return response
