# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import mango
import unittest

class SortTests(mango.UserDocsTextTests):

    @classmethod
    def setUpClass(klass):
        raise unittest.SkipTest('text index service is not available')

    def test_number_sort(self):
        q = {"age": {"$gt": 0}}
        docs = self.db.find(q, sort=["age:number"])
        assert len(docs) == 15
        assert docs[0]["age"] == 22

    def test_number_sort_desc(self):
        q = {"age": {"$gt": 0}}
        docs = self.db.find(q, sort=[{"age": "desc"}])
        assert len(docs) == 15
        assert docs[0]["age"] == 79

        q = {"manager": True}
        docs = self.db.find(q, sort=[{"age:number": "desc"}])
        assert len(docs) == 11
        assert docs[0]["age"] == 79

    def test_string_sort(self):
        q = {"email": {"$gt": None}}
        docs = self.db.find(q, sort=["email:string"])
        assert len(docs) == 15
        assert docs[0]["email"] == "abbottwatson@talkola.com"

    def test_notype_sort(self):
        q = {"email": {"$gt": None}}
        try:
            self.db.find(q, sort=["email"])
        except Exception, e:
            assert e.response.status_code == 400
        else:
            raise AssertionError("Should have thrown error for sort")

    def test_array_sort(self):
        q = {"favorites": {"$exists": True}}
        docs = self.db.find(q, sort=["favorites.[]:string"])
        assert len(docs) == 15
        assert docs[0]["user_id"] == 8

    def test_multi_sort(self):
        q = {"name": {"$exists": True}}
        docs = self.db.find(q, sort=["name.last:string", "age:number"])
        assert len(docs) == 15
        assert docs[0]["name"] == {"last":"Ewing","first":"Shelly"}
        assert docs[1]["age"] == 22

    def test_guess_type_sort(self):
        q = {"$or": [{"age":{"$gt": 0}}, {"email": {"$gt": None}}]}
        docs = self.db.find(q, sort=["age"])
        assert len(docs) == 15
        assert docs[0]["age"] == 22

    def test_guess_dup_type_sort(self):
        q = {"$and": [{"age":{"$gt": 0}}, {"email": {"$gt": None}},
            {"age":{"$lte": 100}}]}
        docs = self.db.find(q, sort=["age"])
        assert len(docs) == 15
        assert docs[0]["age"] == 22

    def test_ambiguous_type_sort(self):
        q = {"$or": [{"age":{"$gt": 0}}, {"email": {"$gt": None}},
            {"age": "34"}]}
        try:
            self.db.find(q, sort=["age"])
        except Exception, e:
            assert e.response.status_code == 400
        else:
            raise AssertionError("Should have thrown error for sort")

    def test_guess_multi_sort(self):
        q = {"$or": [{"age":{"$gt": 0}}, {"email": {"$gt": None}},
            {"name.last": "Harvey"}]}
        docs = self.db.find(q, sort=["name.last", "age"])
        assert len(docs) == 15
        assert docs[0]["name"] == {"last":"Ewing","first":"Shelly"}
        assert docs[1]["age"] == 22

    def test_guess_mix_sort(self):
        q = {"$or": [{"age":{"$gt": 0}}, {"email": {"$gt": None}},
            {"name.last": "Harvey"}]}
        docs = self.db.find(q, sort=["name.last:string", "age"])
        assert len(docs) == 15
        assert docs[0]["name"] == {"last":"Ewing","first":"Shelly"}
        assert docs[1]["age"] == 22
