import argparse
import csv
import json
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'grady.settings')
import secrets
import sys

import django
django.setup()
from django.contrib.auth.models import User

import util.importer
from core.models import Student, Submission


unused_variable = []


def parseme():
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers(dest="command")

    parser.add_argument(
        '-o', '--output',
        help='Where the output goes (not info messages)',
        default=sys.stdout,
        type=argparse.FileType(mode='r'),
    )

    ### parser for printing out new passwordlists ###
    passwordlist = subparsers.add_parser(
        'passwordlist',
        help='all student passwords will be changed and a list of these password will be printed'
    )
    passwordlist.add_argument(
        'instance',
        default='',
        help='name of the instance that generated the passwords'
    )

    ### parser for replacing usernames ###
    replaceusernames = subparsers.add_parser(
        'replaceusernames',
        help='replaces all usernames based on a matrikel_no -> new_name dict (input should be JSON)'
    )
    replaceusernames.add_argument(
        'matno2username_dict',
        help='the mapping as a JSON file',
        default=sys.stdin,
        type=argparse.FileType('r')
    )

    ### parser for enabling or disabling users ###
    enableusers = subparsers.add_parser(
        'enableusers',
        help='All user accounts will be disabled'
    )
    enableusers.add_argument(
        'switch',
        choices=('on', 'off'),
        default='on',
        help='enable all users (on) or disable all (off)'
    )
    filter_group = enableusers.add_mutually_exclusive_group()
    filter_group.add_argument(
        '-e', '--exclude',
        default=(),
        nargs='+',
        help='give exceptions by username in a comma separated list'
    )
    filter_group.add_argument(
        '-i', '--include',
        help='only apply to these users',
        nargs='+',
        default=())

    ### parser for extracting submissions ###
    subparsers.add_parser('extractsubmissions')

    ### parser for extracting submissions ###
    subparsers.add_parser('importer')

    return parser.parse_args()


def handle_passwordlist(output=sys.stdout, instance="", **kwargs):
    with open('/usr/share/dict/words') as words:
        choose_from = list({word.strip().lower()
                            for word in words if 5 < len(word) < 8})

    writer = csv.writer(output)
    writer.writerow(['Name', 'Matrikel', 'Username', 'password', 'instance'])

    for student in Student.objects.all():
        password = ''.join(secrets.choice(choose_from) for _ in range(3))

        student.user.set_password(password)
        student.user.save()

        writer.writerow([student.name, student.matrikel_no,
                         student.user.username, password, instance])


def handle_enableusers(switch, exclude, include, **kwargs):

    if include:
        for user in User.objects.filter(username__in=include):
            user.is_active = switch == 'on'
            user.save()
    else:  # this includes nothing set
        for user in User.objects.exclude(username__in=exclude):
            user.is_active = switch == 'on'
            user.save()


def handle_replaceusernames(matno2username_dict, **kwargs):
    matno2username = json.JSONDecoder().decode(matno2username_dict.read())
    for student in Student.objects.all():
        if student.matrikel_no in matno2username:
            new_name = matno2username[student.matrikel_no]
            student.user.username = new_name
            student.user.save()


def handle_extractsubmissions(output, **kwargs):
    for submission in Submission.objects.filter(feedback__isnull=False).order_by('type'):
        print(submission.feedback.score, repr(submission.text),
              file=open(str(submission.type).replace(' ', '_'), 'a'))


def handle_importer(**kwargs):
    util.importer.start()


def main():
    args = parseme()
    if args.command:
        globals()['handle_' + args.command](**vars(args))


if __name__ == '__main__':
    main()