import httplib2
# TODO: require 2.0+ version of simplejson that doesn't provide unicode keys
import simplejson
import logging
from urlparse import urljoin
import types

# TODO configurable?
BASE_URL = 'http://127.0.0.1:8080/'

class RemoteObject(object):
    fields = {}

    def __init__(self, **kwargs):
        for field_name, field_class in self.fields.iteritems():
            value = kwargs.get(field_name)
            if isinstance(value, list) or isinstance(value, tuple):
                value = []
                for item in value:
                    o = field_class(**item)
                    o.parent = self
                    obj.append(o)
            elif isinstance(value, dict):
                value = field_class(**value)
                value.parent = self # e.g. reference to blog from entry
            setattr(self, field_name, value)

    @classmethod
    def get(cls, id, http=None):
        # TODO accept atom or whatever other response format
        url = cls.url % {'id': id}
        url = urljoin(BASE_URL, url)
        logging.debug('Fetching %s' % (url,))

        if http is None:
            http = httplib2.Http()
        (response, content) = http.request(url)
        logging.debug('Got content %s' % (content,))

        # TODO make sure astropad is returning the proper content type
        #if data and resp.get('content-type') == 'application/json':
        data = simplejson.loads(content)
        return cls(**data)


class User(RemoteObject):
    """User from TypePad API.

    >>> user = User.get(1)
    >>> user.name
    u'Mike Malone'
    >>> user.email
    u'mjmalone@gmail.com'
    """

    fields = {
        'name':  basestring,
        'email': basestring,
        'uri':   basestring,
    }
    url    = r'/users/%(id)s.json'


class Entry(RemoteObject):
    fields = {
        'slug':     basestring,
        'title':    basestring,
        'content':  basestring,
        'pub_date': basestring,
        'mod_date': basestring,
        'authors':  User,
    }


class Blog(RemoteObject):
    """Blog from TypePad API.
    
    >>> blog = Blog.get(1)
    >>> blog.title
    u'Fred'
    """

    fields = {
        'title':    basestring,
        'subtitle': basestring,
        'entries':  Entry,
    }
    url    = r'/blogs/%(id)s.json'

    def get_entries(self):
        pass

@@ -299,16 +299,52 @@
 wargs):%0A
+        self.id = kwargs.get('id')%0A%0A
         
@@ -399,16 +399,16 @@
 tems():%0A
-
         
@@ -1492,16 +1492,510 @@
 *data)%0A%0A
+    def save(self, http=None):%0A        if http is None:%0A            http = httplib2.Http()%0A%0A        body = simplejson.dumps(self.__dict__)%0A%0A        http_extra = %7B'body': body%7D%0A        if self.id is None:%0A            url = self.set_url%0A            http_extra%5B'method'%5D = 'POST'%0A        else:%0A            url = self.url %25 %7B'id': self.id%7D%0A            http_extra%5B'method'%5D = 'PUT'%0A%0A        url = urljoin(BASE_URL, url)%0A        (response, content) = http.request(url, **http_extra)%0A%0A        # yay?%0A%0A
 %0Aclass U
@@ -2341,32 +2341,64 @@
 %0A    fields = %7B%0A
+        'blog_id':  basestring,%0A
         'slug': 
@@ -2567,22 +2567,69 @@
   User,%0A
-
     %7D%0A
+    url = r'/blogs/%25(blog_id)s/entries/%25(id)s'%0A
 %0A%0Aclass 

Save maybe?