from celery import task, chord

from .scan import scanners, heavy_scanners
from .search import search_engines
from .source import sources

from datetime import datetime
from dateutil.tz import tzutc

from models import TopicSet

# validator = jsonschema.Draft3Validator(json.loads(pkgutil.get_data("malware_crawl", "malware_discovery_schema.json")))


def complete_crawl():
    for source in sources:
        source.apply_async(
            link=begin_search.subtask(args=(source,))
        )

    # todo: repeat old searches


@task
def begin_search(keywords, source):
    discovered = datetime.now(tzutc())
    ts = TopicSet.objects.create(
        discovered=discovered,
        source=source
    )
    for keyword in keywords:
        topic = ts.topic_set.create(
            keyword=keyword
        )
        for engine in search_engines:
            engine.apply_async(
                args=(keyword,), link=begin_scan.subtask(args=(engine, topic))
            )


@task
def begin_scan(urls, engine, topic):
    discovered = datetime.now(tzutc())
    search = topic.search_set.create(
        discovered=discovered,
        source=engine
    )
    for url in urls:
        result = search.result_set.create(
            url=url
        )
        for scanner in scanners:

            report = result.malwarereport_set.create(
                reporter=scanner
            )

            scanner.apply_async(
                args=(url,),
                link=begin_store.subtask(
                    args=(report,)
                )
            )

"""
# Check to see if we should scan heavily
def check_opinions(all_opinions, reporters):
    print all_opinions
    return False


@task
def accept_scan(all_opinions, reporters, url, result):
    if check_opinions(all_opinions, reporters):
        for scanner in heavy_scanners:

            report = result.malwarereport_set.create(
                reporter=scanner
            )

            scanner.apply_async(
                args=(url,),
                link=begin_store.subtask(
                    args=(report,)
                )
            )

    for opinions, reporter in zip(all_opinions, reporters):
        begin_store.apply_async(
            args=(opinions, report)
        )
"""


@task
def begin_store(opinions, report):
    for opinion in opinions:
        report.opinion_set.create(
            type=opinion["type"],
            confidence=opinion["confidence"]
        )


@task
def tprint(content):
    print content
