#!/usr/bin/env python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

import mozfile
import mozhttpd
import urllib2
import os
import unittest
import json
import tempfile

here = os.path.dirname(os.path.abspath(__file__))

class ApiTest(unittest.TestCase):
    resource_get_called = 0
    resource_post_called = 0
    resource_del_called = 0

    @mozhttpd.handlers.json_response
    def resource_get(self, request, objid):
        self.resource_get_called += 1
        return (200, { 'called': self.resource_get_called,
                       'id': objid,
                       'query': request.query })

    @mozhttpd.handlers.json_response
    def resource_post(self, request):
        self.resource_post_called += 1
        return (201, { 'called': self.resource_post_called,
                       'data': json.loads(request.body),
                       'query': request.query })

    @mozhttpd.handlers.json_response
    def resource_del(self, request, objid):
        self.resource_del_called += 1
        return (200, { 'called': self.resource_del_called,
                       'id': objid,
                       'query': request.query })

    def get_url(self, path, server_port, querystr):
        url = "http://127.0.0.1:%s%s" % (server_port, path)
        if querystr:
            url += "?%s" % querystr
        return url

    def try_get(self, server_port, querystr):
        self.resource_get_called = 0

        f = urllib2.urlopen(self.get_url('/api/resource/1', server_port, querystr))
        try:
            self.assertEqual(f.getcode(), 200)
        except AttributeError:
            pass  # python 2.4
        self.assertEqual(json.loads(f.read()), { 'called': 1, 'id': str(1), 'query': querystr })
        self.assertEqual(self.resource_get_called, 1)

    def try_post(self, server_port, querystr):
        self.resource_post_called = 0

        postdata = { 'hamburgers': '1234' }
        try:
            f = urllib2.urlopen(self.get_url('/api/resource/', server_port, querystr),
                                data=json.dumps(postdata))
        except urllib2.HTTPError, e:
            # python 2.4
            self.assertEqual(e.code, 201)
            body = e.fp.read()
        else:
            self.assertEqual(f.getcode(), 201)
            body = f.read()
        self.assertEqual(json.loads(body), { 'called': 1,
                                             'data': postdata,
                                             'query': querystr })
        self.assertEqual(self.resource_post_called, 1)

    def try_del(self, server_port, querystr):
        self.resource_del_called = 0

        opener = urllib2.build_opener(urllib2.HTTPHandler)
        request = urllib2.Request(self.get_url('/api/resource/1', server_port, querystr))
        request.get_method = lambda: 'DEL'
        f = opener.open(request)

        try:
            self.assertEqual(f.getcode(), 200)
        except AttributeError:
            pass  # python 2.4
        self.assertEqual(json.loads(f.read()), { 'called': 1, 'id': str(1), 'query': querystr })
        self.assertEqual(self.resource_del_called, 1)

    def test_api(self):
        httpd = mozhttpd.MozHttpd(port=0,
                                  urlhandlers = [ { 'method': 'GET',
                                                    'path': '/api/resource/([^/]+)/?',
                                                    'function': self.resource_get },
                                                  { 'method': 'POST',
                                                    'path': '/api/resource/?',
                                                    'function': self.resource_post },
                                                  { 'method': 'DEL',
                                                    'path': '/api/resource/([^/]+)/?',
                                                    'function': self.resource_del }
                                                  ])
        httpd.start(block=False)

        server_port = httpd.httpd.server_port

        # GET
        self.try_get(server_port, '')
        self.try_get(server_port, '?foo=bar')

        # POST
        self.try_post(server_port, '')
        self.try_post(server_port, '?foo=bar')

        # DEL
        self.try_del(server_port, '')
        self.try_del(server_port, '?foo=bar')

        # GET: By default we don't serve any files if we just define an API
        exception_thrown = False
        try:
            urllib2.urlopen(self.get_url('/', server_port, None))
        except urllib2.HTTPError, e:
            self.assertEqual(e.code, 404)
            exception_thrown = True
        self.assertTrue(exception_thrown)

    def test_nonexistent_resources(self):
        # Create a server with a placeholder handler so we don't fall back
        # to serving local files
        httpd = mozhttpd.MozHttpd(port=0)
        httpd.start(block=False)
        server_port = httpd.httpd.server_port

        # GET: Return 404 for non-existent endpoint
        exception_thrown = False
        try:
            urllib2.urlopen(self.get_url('/api/resource/', server_port, None))
        except urllib2.HTTPError, e:
            self.assertEqual(e.code, 404)
            exception_thrown = True
        self.assertTrue(exception_thrown)

        # POST: POST should also return 404
        exception_thrown = False
        try:
            urllib2.urlopen(self.get_url('/api/resource/', server_port, None),
                            data=json.dumps({}))
        except urllib2.HTTPError, e:
            self.assertEqual(e.code, 404)
            exception_thrown = True
        self.assertTrue(exception_thrown)

        # DEL: DEL should also return 404
        exception_thrown = False
        try:
            opener = urllib2.build_opener(urllib2.HTTPHandler)
            request = urllib2.Request(self.get_url('/api/resource/', server_port,
                                                   None))
            request.get_method = lambda: 'DEL'
            opener.open(request)
        except urllib2.HTTPError:
            self.assertEqual(e.code, 404)
            exception_thrown = True
        self.assertTrue(exception_thrown)

    def test_api_with_docroot(self):
        httpd = mozhttpd.MozHttpd(port=0, docroot=here,
                                  urlhandlers = [ { 'method': 'GET',
                                                    'path': '/api/resource/([^/]+)/?',
                                                    'function': self.resource_get } ])
        httpd.start(block=False)
        server_port = httpd.httpd.server_port

        # We defined a docroot, so we expect a directory listing
        f = urllib2.urlopen(self.get_url('/', server_port, None))
        try:
            self.assertEqual(f.getcode(), 200)
        except AttributeError:
            pass  # python 2.4
        self.assertTrue('Directory listing for' in f.read())

        # Make sure API methods still work
        self.try_get(server_port, '')
        self.try_get(server_port, '?foo=bar')

class ProxyTest(unittest.TestCase):

    def tearDown(self):
        # reset proxy opener in case it changed
        urllib2.install_opener(None)

    def test_proxy(self):
        docroot = tempfile.mkdtemp()
        self.addCleanup(mozfile.remove, docroot)
        hosts = ('mozilla.com', 'mozilla.org')
        unproxied_host = 'notmozilla.org'
        def url(host): return 'http://%s/' % host

        index_filename = 'index.html'
        def index_contents(host): return '%s index' % host

        index = file(os.path.join(docroot, index_filename), 'w')
        index.write(index_contents('*'))
        index.close()

        httpd = mozhttpd.MozHttpd(port=0, docroot=docroot)
        httpd.start(block=False)
        server_port = httpd.httpd.server_port

        proxy_support = urllib2.ProxyHandler({'http': 'http://127.0.0.1:%d' %
                                              server_port})
        urllib2.install_opener(urllib2.build_opener(proxy_support))

        for host in hosts:
            f = urllib2.urlopen(url(host))
            try:
                self.assertEqual(f.getcode(), 200)
            except AttributeError:
                pass  # python 2.4
            self.assertEqual(f.read(), index_contents('*'))

        httpd.stop()

        # test separate directories per host

        httpd = mozhttpd.MozHttpd(port=0, docroot=docroot, proxy_host_dirs=True)
        httpd.start(block=False)
        server_port = httpd.httpd.server_port

        proxy_support = urllib2.ProxyHandler({'http': 'http://127.0.0.1:%d' %
                                              server_port})
        urllib2.install_opener(urllib2.build_opener(proxy_support))

        # set up dirs
        for host in hosts:
            os.mkdir(os.path.join(docroot, host))
            file(os.path.join(docroot, host, index_filename), 'w') \
                .write(index_contents(host))

        for host in hosts:
            f = urllib2.urlopen(url(host))
            try:
                self.assertEqual(f.getcode(), 200)
            except AttributeError:
                pass  # python 2.4
            self.assertEqual(f.read(), index_contents(host))

        exc = None
        try:
            urllib2.urlopen(url(unproxied_host))
        except urllib2.HTTPError, e:
            exc = e
        self.assertNotEqual(exc, None)
        self.assertEqual(exc.code, 404)


if __name__ == '__main__':
    unittest.main()
