import json
import logging

from knowledge_base import KnowledgeBase
from modifiable_property import ModifiableProperty

examples = [
    {
        "text": "icecream is cold",
        "parsed": ("exists-property-with-value", 'icecream', 'cold'),
    },
    {
        "text": "is icecream cold?",
        "parsed": ("question", ("exists-property-with-value", 'icecream', 'cold'))
    },
    {
        "text": "lava is dangerous",
        "parsed": ("exists-property-with-value", 'lava', 'dangerous')
    },
    {
        "text": "is lava dangerous?",
        "parsed": ("question", ("exists-property-with-value", 'lava', 'dangerous')),
    },
    {
        "text": "earth is a planet",
        "parsed": ("pertenence-to-group", 'earth', 'planet'),
    },
    {
        "text": "io is a moon",
        "parsed": ("pertenence-to-group", 'io', 'moon'),
    },
    {
        "text": "is earth a moon?",
        "parsed": ("question", ("pertenence-to-group", 'earth', 'moon')),
    },
    {
        "text": "Green is a color",
        "parsed": ("pertenence-to-group", 'green', 'color'),
    },
    {
        "text": "a plane can fly",
        "parsed": ("has-capacity", 'plane', 'fly')
    },
    {
        "text": "a wale can swim",
        "parsed": ("has-capacity", 'wale', 'swim')
    },
]

base_knowledge = {
    'icecream': {
        "groups": set(['noun', 'object', 'comestible', 'sweet']),
    },
    'lava': {
        "groups": set(['noun', 'object']),
    },
    'earth': {
        "groups": set(['noun', 'object', 'planet']),
    },
    'io': {
        "groups": set(['noun', 'object']),
    },
    'green': {
        "groups": set(['noun', 'color', 'concept']),
    },
    'plane': {
        "groups": set(['noun', 'object', 'vehicle', 'fast']),
    },
    'car': {
        "groups": set(['noun', 'object', 'vehicle', 'slow-ish']),
    },
    'wale': {
        "groups": set(['noun', 'object', 'living-being']),
    },
    'cold': {
        "groups": set(['property', 'temperature']),
        "as_property": "temperature",
    },
    'dangerous': {
        "groups": set(['property']),
        "as_property": "safety",
    },
    'planet': {
        "groups": set(['noun', 'group']),
    },
    'moon': {
        "groups": set(['noun', 'group']),
    },
    'color': {
        "groups": set(['property', 'group']),
    },
    'fly': {
        "groups": set(['verb']),
    },
    'swim': {
        "groups": set(['verb']),
    },
}


def test_assumption(expectedResponse, knowledge, query):
    logging.info("Query: {}".format(query['text']))
    logging.info("Expected: {}".format(expectedResponse))

    result, abstract_tree, diff = knowledge.process(query['text'])
    end_result = result.getter() if isinstance(result, ModifiableProperty) else result

    logging.info("\x1b[0;3{}mResult: {}\x1b[0m".format("1" if end_result != expectedResponse else "2", end_result))
    assert(end_result == expectedResponse)


def main():
    knowledge = KnowledgeBase(
        knowledge=base_knowledge,
    )

    differences = knowledge.train(examples)

    logging.info("----")
    logging.info(differences())
    logging.info("----")

    test_assumption(True, knowledge, {'text': 'earth is a planet'})
    test_assumption(True, knowledge, {'text': 'is lava dangerous?'})
    for test in [{'text': 'a bus can run'}, {'text': 'io is a moon'}]:
        row = test['text']
        result, inferred_tree, differences = knowledge.process(row)

        logging.info("result:", result)
        logging.info(differences())
        logging.info("---")
    logging.info('-----')
    logging.info(json.dumps(sorted(knowledge.knowledge.keys()), indent=4))
    logging.info('-----')

    queryTrue = {
        "text": "is io a moon?",
        "parsed": ("question", ("pertenence-to-group", "io", "moon"))
    }
    queryFalse = {
        "text": "is io a planet?",
        "parsed": ("question", ("pertenence-to-group", "io", "planet"))
    }

    test_assumption(False, knowledge, queryFalse)
    test_assumption(True, knowledge, queryTrue)

if __name__ == '__main__':
    main()
