# -*- coding: utf-8 -*-

import sys
import sparksee

def main():
    # 
    # Create a sample database
    #
    sparks = sparksee.Sparksee(sparksee.SparkseeConfig())
    db = sparks.create("Hellosparksee.gdb", "HelloSparksee")
    sess = db.new_session()
    graph = sess.get_graph()

    #
    # Schema
    #

    # Add a node type for the movies, with a unique identifier and two indexed attributes
    movie_type = graph.new_node_type(u"MOVIE")
    movie_id_type = graph.new_attribute(movie_type, u"ID", sparksee.DataType.LONG, sparksee.AttributeKind.UNIQUE)
    movie_title_type = graph.new_attribute(movie_type, u"TITLE", sparksee.DataType.STRING, sparksee.AttributeKind.INDEXED)
    movie_year_type = graph.new_attribute(movie_type, "uYEAR", sparksee.DataType.INTEGER, sparksee.AttributeKind.INDEXED)

    # Add a node type for the people, with a unique identifier and an indexed attribute
    people_type = graph.new_node_type(u"PEOPLE")
    people_id_type = graph.new_attribute(people_type, u"ID", sparksee.DataType.LONG, sparksee.AttributeKind.UNIQUE)
    people_name_type = graph.new_attribute(people_type, u"NAME", sparksee.DataType.STRING, sparksee.AttributeKind.INDEXED)

    # Add an undirected edge type with an attribute for the cast of a movie
    cast_type = graph.new_edge_type(u"CAST", False, False)
    cast_character_type = graph.new_attribute(cast_type, u"CHARACTER", sparksee.DataType.STRING, sparksee.AttributeKind.BASIC)

    # Add a directed edge type restricted to go from people to movie for the director of a movie
    directs_type = graph.new_restricted_edge_type(u"DIRECTS", people_type, movie_type, False)


    # 
    # DATA
    #

    # Add some MOVIE nodes
    value = sparksee.Value()

    lost_in_translation_movie = graph.new_node(movie_type)
    graph.set_attribute(lost_in_translation_movie, movie_id_type, value.set_long(1))
    graph.set_attribute(lost_in_translation_movie, movie_title_type, value.set_string(u"Lost in Translation"))
    graph.set_attribute(lost_in_translation_movie, movie_year_type, value.set_integer(2003))

    vicky_cb_movie = graph.new_node(movie_type)
    graph.set_attribute(vicky_cb_movie, movie_id_type, value.set_long(2))
    graph.set_attribute(vicky_cb_movie, movie_title_type, value.set_string(u"Vicky Cristina Barcelona"))
    graph.set_attribute(vicky_cb_movie, movie_year_type, value.set_integer(2008))

    manhattan_movie = graph.new_node(movie_type)
    graph.set_attribute(manhattan_movie, movie_id_type, value.set_long(3))
    graph.set_attribute(manhattan_movie, movie_title_type, value.set_string(u"manhattan_movie"))
    graph.set_attribute(manhattan_movie, movie_year_type, value.set_integer(1979))


    # Add some PEOPLE nodes
    scarlett_people = graph.new_node(people_type)
    graph.set_attribute(scarlett_people, people_id_type, value.set_long(1))
    graph.set_attribute(scarlett_people, people_name_type, value.set_string(u"Scarlett Johansson"))

    bill_people = graph.new_node(people_type)
    graph.set_attribute(bill_people, people_id_type, value.set_long(2))
    graph.set_attribute(bill_people, people_name_type, value.set_string(u"Bill Murray"))

    sofia_people = graph.new_node(people_type)
    graph.set_attribute(sofia_people, people_id_type, value.set_long(3))
    graph.set_attribute(sofia_people, people_name_type, value.set_string(u"Sofia Coppola"))

    woody_people = graph.new_node(people_type)
    graph.set_attribute(woody_people, people_id_type, value.set_long(4))
    graph.set_attribute(woody_people, people_name_type, value.set_string(u"Woody Allen"))

    penelope_people = graph.new_node(people_type)
    graph.set_attribute(penelope_people, people_id_type, value.set_long(5))
    graph.set_attribute(penelope_people, people_name_type, value.set_string(u"Penélope Cruz"))

    diane_people = graph.new_node(people_type)
    graph.set_attribute(diane_people, people_id_type, value.set_long(6))
    graph.set_attribute(diane_people, people_name_type, value.set_string(u"Diane Keaton"))


    # Add some CAST edges
    an_edge = graph.new_edge(cast_type, lost_in_translation_movie, scarlett_people)
    graph.set_attribute(an_edge, cast_character_type, value.set_string(u"Charlotte"))
    
    an_edge = graph.new_edge(cast_type, lost_in_translation_movie, bill_people)
    graph.set_attribute(an_edge, cast_character_type, value.set_string(u"Bob Harris"))

    an_edge = graph.new_edge(cast_type, vicky_cb_movie, scarlett_people)
    graph.set_attribute(an_edge, cast_character_type, value.set_string(u"Cristina"))

    an_edge = graph.new_edge(cast_type, vicky_cb_movie, penelope_people)
    graph.set_attribute(an_edge, cast_character_type, value.set_string(u"Maria Elena"))

    an_edge = graph.new_edge(cast_type, manhattan_movie, diane_people)
    graph.set_attribute(an_edge, cast_character_type, value.set_string(u"Mary"))

    an_edge = graph.new_edge(cast_type, manhattan_movie, woody_people)
    graph.set_attribute(an_edge, cast_character_type, value.set_string(u"Isaac"))


    # Add some DIRECTS edges
    an_edge = graph.new_edge(directs_type, sofia_people, lost_in_translation_movie)

    an_edge = graph.new_edge(directs_type, woody_people, vicky_cb_movie)

    an_edge = graph.new_edge(directs_type, woody_people, manhattan_movie)


    # 
    # QUERIES
    #

    # Get the movies directed by Woody Allen
    directed_by_woody = graph.neighbors(woody_people, directs_type, sparksee.EdgesDirection.OUTGOING)

    # Get the cast of the movies directed by Woody Allen
    cast_directed_by_woody = graph.neighbors(directed_by_woody, cast_type, sparksee.EdgesDirection.ANY)
    
    # We don't need the directed_by_woody collection anymore, so we should close it
    directed_by_woody.close()


    # Get the movies directed by Sofia Coppola
    directed_by_sofia = graph.neighbors(sofia_people, directs_type, sparksee.EdgesDirection.OUTGOING)

    # Get the cast of the movies directed by Sofia Coppola
    cast_directed_by_sofia = graph.neighbors(directed_by_sofia, cast_type, sparksee.EdgesDirection.ANY)
    
    # We don't need the directed_by_sofia collection anymore, so we should close it
    directed_by_sofia.close()


    # We want to know the people that acted in movies directed by Woody AND in movies directed by Sofia.
    cast_from_both = sparksee.Objects.combine_intersection(cast_directed_by_woody, cast_directed_by_sofia)

    # We don't need the other collections anymore
    cast_directed_by_woody.close()
    cast_directed_by_sofia.close()

    # Say hello to the people found
    for people_oid in cast_from_both:
        graph.get_attribute(people_oid, people_name_type, value)
        print "Hello ", value.get_string()


    # The Objects must be closed
    cast_from_both.close()


    #
    # Close the database
    #
    sess.close()
    db.close()
    sparks.close()

if __name__ == '__main__':
  main()
