from elixir import Entity, has_field, has_many, belongs_to
from elixir import Unicode, objectstore, metadata
from elixir.events import after_update
from elixir.ext.versioned import acts_as_versioned
from elixir.ext.encrypted import acts_as_encrypted


#
# define our entities
#

class Person(Entity):
    has_field('name', Unicode)
    has_field('email', Unicode)
    has_field('password', Unicode)
    
    has_many('articles', of_kind='Article', inverse='author')
    acts_as_encrypted(for_fields=['password'], with_secret='s3kr1t!')


class Article(Entity):
    has_field('title', Unicode)
    has_field('description', Unicode)
    has_field('content', Unicode)
    
    belongs_to('author', of_kind='Person', inverse='articles')
    acts_as_versioned()


if __name__ == '__main__':
    metadata.bind = 'sqlite:///'
    metadata.create_all()
    
    jonathan = Person(
        name='Jonathan', 
        email='jonathan-nospam@cleverdevil.org',
        password='s3cr3t'
    )
    blog_post = Article(
        title='Some Blog Post',
        description='A blog post on some subject',
        content='Draft content for blog post',
        author=jonathan
    )
    objectstore.flush(); objectstore.clear()
    
    jonathan = Person.query().get_by(name='Jonathan')
    print jonathan.name
    print jonathan.articles[0].title
    print jonathan.articles[0].author.name
    
    # update the article, triggering a new version
    jonathan.articles[0].content = 'Updated content for blog post'
    objectstore.flush(); objectstore.clear()
    
    # fetch it back out again
    article = Article.query().get(1)
    assert article.version == 2
    print article.timestamp
    assert article.content == 'Updated content for blog post'
    
    # look at previous versions and compare them with our latest version
    assert article.versions[0].content == 'Draft content for blog post'
    print article.versions[0].timestamp
    print article.compare_with(article.versions[0])
    
    # rollback to old version
    article.revert()
    objectstore.flush(); objectstore.clear()
    
    # fetch it back to make sure its the old version now
    article = Article.query().get(1)
    assert article.version == 1
    assert article.content == 'Draft content for blog post'

