from django.conf import settings
from django.core.management.base import BaseCommand
from moss import *

from judge.models import Contest, ContestParticipation, Submission


class Command(BaseCommand):
    help = 'Checks for duplicate code using MOSS'

    LANG_MAPPING = {
        ('C++', MOSS_LANG_CC),
        ('C', MOSS_LANG_C),
        ('Java', MOSS_LANG_JAVA),
        ('Python', MOSS_LANG_PYTHON),
        ('Pascal', MOSS_LANG_PASCAL),
    }

    def add_arguments(self, parser):
        parser.add_argument('contest', help='the id of the contest')

    def handle(self, *args, **options):
        moss_api_key = settings.MOSS_API_KEY
        if moss_api_key is None:
            print('No MOSS API Key supplied')
            return
        contest = options['contest']

        for problem in Contest.objects.get(key=contest).problems.order_by('code'):
            print('========== %s / %s ==========' % (problem.code, problem.name))
            for dmoj_lang, moss_lang in self.LANG_MAPPING:
                print("%s: " % dmoj_lang, end=' ')
                subs = Submission.objects.filter(
                    contest__participation__virtual__in=(ContestParticipation.LIVE, ContestParticipation.SPECTATE),
                    contest__participation__contest__key=contest,
                    result='AC', problem__id=problem.id,
                    language__common_name=dmoj_lang,
                ).values_list('user__user__username', 'source__source')
                if not subs:
                    print('<no submissions>')
                    continue

                moss_call = MOSS(moss_api_key, language=moss_lang, matching_file_limit=100,
                                 comment='%s - %s' % (contest, problem.code))

                users = set()

                for username, source in subs:
                    if username in users:
                        continue
                    users.add(username)
                    moss_call.add_file_from_memory(username, source.encode('utf-8'))

                print('(%d): %s' % (subs.count(), moss_call.process()))