# Copyright 2023 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE 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.
#
# CIRCLE 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 CIRCLE.  If not, see <http://www.gnu.org/licenses/>.

import random, string
from contextlib import contextmanager
from datetime import timedelta
from dbm import dumb
from functools import partial
from importlib import import_module
from ipaddress import ip_interface
from logging import getLogger
from urllib import request
from warnings import warn
from xml.dom.minidom import Text

import django.conf
from django.contrib.auth.models import User
from django.core import signing
from django.core.exceptions import PermissionDenied
from django.db.models import (BooleanField, CharField, DateTimeField,
                              IntegerField, ForeignKey, Manager,
                              ManyToManyField, SET_NULL, TextField, Model)
from django.db import IntegrityError
from django.dispatch import Signal
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _, ugettext_noop

import jinja2

from passlib.hash import sha512_crypt
import yaml
import urllib3, json

from model_utils import Choices
from model_utils.managers import QueryManager
from model_utils.models import TimeStampedModel, StatusModel
from taggit.managers import TaggableManager
from simplesshkey.models import UserKey
from django.db import models

from acl.models import AclBase
from django import forms
from common.models import (
    activitycontextimpl, create_readable, HumanReadableException,
)
from common.operations import OperatedMixin
from storage.models import DataStore
from vm.models import Instance, InstanceTemplate, Lease, Interface, Node, InstanceActivity


class Exam(AclBase):
    """Exam template.
    """
    ACL_LEVELS = (
        ('user', _('user')),          # see all details
        ('operator', _('operator')),
        ('owner', _('owner')),        # superuser, can delete, delegate perms
    )
    name = CharField(max_length=100, verbose_name=_('name'), help_text=_('Human readable name of the exam.'))
    description = TextField(verbose_name=_('description'), blank=True)
    template = ForeignKey(InstanceTemplate, on_delete=models.CASCADE, null=True)
    examinees = ManyToManyField(User, related_name="examinees")
    instances = ManyToManyField(Instance, related_name="instances")
    owner = ForeignKey(User, on_delete=models.CASCADE)

    class Meta:
        app_label = 'exam'
        db_table = 'exam'
        ordering = ('name', )
        permissions = (
            ('create_exam', _('Can create an instance temp late.')),
            ('start_exam', _('Can start VMs for a group.')),
        )
        verbose_name = _('exam')
        verbose_name_plural = _('exams')

    def get_absolute_url(self):
        return reverse('dashboard.views.exam-detail', kwargs=({'pk': self.pk}))

    def __str__(self):
        return self.name
