from collections import deque
import json
import os.path
import sys
import time

def load_json(filename):
    with open(filename, "rb") as f:
        return json.loads(f.read())

def load(name):
    try:
        return load_json("%s.json" % name)
    except:
        return []

def fetch(type, id):
    filename = "%s/%s.json" % (type, id)
    return load_json(filename)

def fetch_character(id):
    return fetch("character", id)

def fetch_game(id):
    return fetch("game", id)

def p(s):
    print s.encode(sys.stdout.encoding, 'replace')

done = load("done")
todo = load("todo")
seen = done + todo
seen_games = {id: (name, prev) for type, id, name, degree, prev in seen if type == "game"}
seen_characters = {id: (name, prev, degree) for type, id, name, degree, prev in seen if type == "character"}

q = sys.argv[1]
print "Searching %s..." % q
try:
    id = int(q)
except:
    id = None
if id is not None and id in seen_characters:
    name, prev, degree = seen_characters[id]
    matches = [(id, name, prev, degree)]
else:
    matches = [(id, name, prev, degree) for type, id, name, degree, prev in seen 
               if type == "character" and q.lower() in name.lower()]
if not matches:
    print "Not found"
elif len(matches) > 1:
    print "Found %s matches:" % len(matches)
    for id, name, prev, degree in matches:
        if prev is None:
            p("%s (%s, %s)" % (name, id, degree))
        else:
            p("%s (%s, %s) from %s" % (name, id, degree, seen_games[prev][0]))
else:
    id, name, prev, degree = matches[0]
    print "Found one match (%s, %s):" % (id, degree)
    game_id = prev
    while prev is not None:
        game, prev = seen_games[prev]
        p("%s from %s" % (name, game))
        name, prev, degree = seen_characters[prev]
    p(name)
    print

    try:
        c = fetch_character(id)
        p(c["results"]["deck"])
        print
    except:
        pass

    if game_id is not None:
        try:
            g = fetch_game(game_id)
            p(g["results"]["deck"])
            print
        except:
            pass

    if '-r' in sys.argv:
        print "=== REVERSE search..."
        rev_games = {}
        rev_characters = {}
        for type, sid, sname, degree, prev in seen:
            if type == "game":
                rev_games.setdefault(prev, []).append((sname, sid))
            elif type == "character":
                rev_characters.setdefault(prev, []).append((sname, sid))
        todo = deque([("character", matches[0][1], id)])
        while todo:
            type, name, id = todo.popleft()
            if type == "character":
                for game_name, game_id in rev_games.get(id, []):
                    p("   %s was in %s" % (name, game_name))
                    todo.append(("game", game_name, game_id))
            if type == "game":
                for char_name, char_id in rev_characters.get(id, []):
                    p("   %s had %s" % (name, char_name))
                    todo.append(("character", char_name, char_id))
