__version__ = "dev"

__author__ = "Donald Stufft"
__email__ = "donald.stufft@gmail.com"

__description__ = "A library that makes consuming a ReST API easier and more convenient"
__url__ = "https://github.com/dstufft/slumber/"

__all__ = ["Resource", "API"]

import copy
import json # @@@ Should we look for one with speedups?
import urlparse

from slumber.http import HttpClient

class Resource(object):

    def __init__(self, domain, endpoint=None):
        self.domain = domain
        self.endpoint = endpoint

        self.http_client = HttpClient()

    def __call__(self, id):
        obj = copy.deepcopy(self)
        obj.object_id = id
        return obj
    
    def get(self, **kwargs):
        url = urlparse.urljoin(self.domain, self.endpoint)

        if hasattr(self, "object_id"):
            url = urlparse.urljoin(url, str(self.object_id))
        
        resp, content = self.http_client.get(url)
        return json.loads(content)


class APIMeta(object):

    resources = {}
    http = {
        "schema": "http",
        "hostname": None,
        "port": "80",
        "path": "/",

        "params": "",
        "query": "",
        "fragment": "",
    }

    def __init__(self, **kwargs):
        for key, value in kwargs.iteritems():
            default_value = getattr(self, key)
            
            if isinstance(default_value, dict) and isinstance(value, dict):
                setattr(self, key, default_value.update(value))
            else:
                setattr(self, key, value)

    @property
    def base_url(self):
        ORDERING = ["schema", "hostname", "port", "path", "params", "query", "fragment"]
        urlparts = []
        for key in ORDERING:
            if key in ["path"]:
                urlparts.append("")
            else:
                urlparts.append(self.http[key])
        return urlparse.urlunparse(urlparts[:1] + [":".join([str(x) for x in urlparts[1:3]])] + urlparts[3:])

    @property
    def api_url(self):
        ORDERING = ["schema", "hostname", "port", "path", "params", "query", "fragment"]
        urlparts = []
        for key in ORDERING:
            urlparts.append(self.http[key])
        return urlparse.urlunparse(urlparts[:1] + [":".join([str(x) for x in urlparts[1:3]])] + urlparts[3:])


class API(object):

    def __init__(self, api_url=None):
        class_meta = getattr(self, "Meta", None)
        if class_meta is not None:
            keys = [x for x in dir(class_meta) if not x.startswith("_")]
            meta_dict = dict([(x, getattr(class_meta, x)) for x in keys])
        else:
            meta_dict = {}

        self._meta = APIMeta(**meta_dict)

        if api_url is not None:
            # Attempt to parse the url into it's parts
            parsed = urlparse.urlparse(api_url)
            for key in self._meta.http.keys():
                val = getattr(parsed, key, None)
                if val:
                    self._meta.http[key] = val

        self.http_client = HttpClient()

        self.discover_resources()

    def __getattr__(self, item):
        if item != "Meta":
            try:
                return self._meta.resources[item]
            except KeyError:
                self._meta.resources[item] = Resource(self._meta.base_url)
                return self._meta.resources[item]

    def discover_resources(self):
        resp, content = self.http_client.get(self._meta.api_url)

        resources = json.loads(content)
        for name, resource in resources.iteritems():
            kwargs = {
                "domain": self._meta.base_url,
                "endpoint": resource.get("list_endpoint", self._meta.http["path"] + name + "/")
            }
            self._meta.resources[name] = Resource(**kwargs)
@@ -2282,32 +2282,62 @@
 s API(object):%0A%0A
+    class Meta:%0A        pass%0A%0A
     def __init__
@@ -3090,39 +3090,8 @@
 m):%0A
-        if item != %22Meta%22:%0A    
     
@@ -3099,20 +3099,16 @@
    try:%0A
-    
         
@@ -3153,20 +3153,16 @@
         
- 
-   
 except K
@@ -3170,20 +3170,16 @@
 yError:%0A
-    
         
@@ -3237,28 +3237,24 @@
 a.base_url)%0A
-    
             

add an empty Meta class to API so we can remove the specialcase of Meta from __getattr__