from cStringIO import StringIO
import urllib2
import urlparse

import lxml
import pytest

import gaereader

from google.appengine.ext import ndb, testbed
testbed = testbed.Testbed()
testbed.activate()
testbed.init_urlfetch_stub()

class Result(str):
  def __init__(self, value):
    super(Result, self).__init__(value)
    self.content = value

@ndb.tasklet
def mock_urlfetch(self, url, **_kwargv):
  if url == "https://www.google.com/accounts/ClientLogin":
    result = "Auth=DUMMY"
  elif url == "http://www.google.com/reader/api/0/tag/list?output=json":
    result = '{"tags": [{"id":"user/0/"}]}'
  elif url in [
               "http://www.google.com/reader/atom/feed/feed?n=2",
               "http://www.google.com/reader/atom/feed/url",
               "http://www.google.com/reader/atom/user/0/label/tag",
               "http://www.google.com/reader/atom/user/-/state/com.google/reading-list",
               "http://www.google.com/reader/atom/user/-/state/com.google/read",
               "http://www.google.com/reader/atom/user/-/state/com.google/starred",
               "http://www.google.com/reader/atom/user/-/state/com.google/fresh",
               "http://www.google.com/reader/atom/user/-/state/com.google/broadcast",
               "http://www.google.com/reader/atom/user/-/state/com.google/state",
               "url",
               "url?c=c&r=o",
               "url?output=format",
              ]:
    result = '<?xml version="1.0"?><feed><entry><id>id</id></entry></feed>'
  elif url.startswith("http://www.google.com/reader/api/0/search/items/ids?"):
    query = dict(urlparse.parse_qsl(urlparse.urlparse(url).query))
    if "s" in query:
      assert query["s"] == "user/0/label/tag"
    result = '{"results":[]}'
  elif (url in [
               "http://www.google.com/reader/api/0/token",
               "http://www.google.com/reader/api/0/subscription/list?output=json",
               "http://www.google.com/reader/api/0/preference/list?output=json",
               "http://www.google.com/reader/api/0/unread-count?output=json",
               ]
     or url.startswith("http://www.google.com/reader/api/0/stream/items/contents?ck=")
     or url.startswith("http://www.google.com/reader/api/0/stream/contents/user%2F0%2Flabel%2Ftag?ck=")
     or url.startswith("http://www.google.com/reader/api/0/stream/contents/feed/feed_url?ck=")
     or url.startswith("http://www.google.com/reader/api/0/subscription/quickadd?ck=")):
    result = '{}'
  elif url in [
               "http://www.google.com/reader/api/0/subscription/edit?client=mekk.reader_client",
               "http://www.google.com/reader/api/0/disable-tag?client=mekk.reader_client",
              ]:
    result = 'OK'
  else:
    raise ValueError(url)

  result = Result(result)
  result.status_code = 200
  result.url = url
  raise ndb.Return(result)


def pytest_funcarg__mock(request):

  def setup():
    mock = request.getfuncargvalue("monkeypatch")
    mock.setattr(ndb.Context, "urlfetch", mock_urlfetch)
    return mock

  def teardown(mock):
    mock.undo()

  return request.cached_setup(setup=setup, teardown=teardown, scope="function")

def test_GoogleReaderClient(mock):
  c = gaereader.GoogleReaderClient("login", "password")

  future = c.tag_id("tag")
  assert future.get_exception() is None
  assert future.get_result() == "user/0/label/tag"

  future = c.get_my_id()
  assert future.get_exception() is None
  assert future.get_result() == "0"

  future = c.feed_item_id("feed")
  assert future.get_exception() is None
  assert future.get_result() == "id"

  future = c.get_feed_atom("url")
  assert future.get_exception() is None
  assert isinstance(future.get_result(), lxml.etree._Element)

  future = c.get_reading_list_atom()
  assert future.get_exception() is None
  assert isinstance(future.get_result(), lxml.etree._Element)

  future = c.get_read_atom()
  assert future.get_exception() is None
  assert isinstance(future.get_result(), lxml.etree._Element)

  future = c.get_tagged_atom("tag")
  assert future.get_exception() is None
  assert isinstance(future.get_result(), lxml.etree._Element)

  future = c.get_starred_atom()
  assert future.get_exception() is None
  assert isinstance(future.get_result(), lxml.etree._Element)

  future = c.get_fresh_atom()