/*
 * Copyright (c) 2008 - 2013 MongoDB, Inc. <http://mongodb.com>
 *
 * 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.
 */

package org.mongodb.morphia.aggregation;

import org.bson.types.ObjectId;
import org.junit.Assert;
import org.junit.Test;
import org.mongodb.morphia.TestBase;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.query.MorphiaIterator;

import java.util.Arrays;
import java.util.List;

public class AggregationTest extends TestBase {
    @Test
    public void testOut() {
        getDs().save(new Book("The Banquet", "Dante", 2),
                     new Book("Divine Comedy", "Dante", 1),
                     new Book("Eclogues", "Dante", 2),
                     new Book("The Odyssey", "Homer", 10),
                     new Book("Iliad", "Homer", 10));

        MorphiaIterator<Author, Author> aggregate = getDs().createAggregation(Book.class, Author.class)
                                                        .group("author", Group.grouping("books", Group.push("title")))
                                                        .out()
                                                        .aggregate();
        Assert.assertEquals(2, getDs().getCollection(Author.class).count());
        Author author = aggregate.next();
        Assert.assertEquals("Homer", author.getName());
        Assert.assertEquals(Arrays.asList("The Odyssey", "Iliad"), author.getBooks());
        
        getDs().createAggregation(Book.class, Author.class)
            .group("author", Group.grouping("books", Group.push("title")))
            .out("different")
            .aggregate();

        Assert.assertEquals(2, getDb().getCollection("different").count());
    }

    @Entity("books")
    private static class Book {
        @Id
        private ObjectId id;
        private String title;
        private String author;
        private Integer copies;

        private Book() {
        }

        private Book(final String title, final String author, final Integer copies) {
            this.title = title;
            this.author = author;
            this.copies = copies;
        }

        private ObjectId getId() {
            return id;
        }

        private void setId(final ObjectId id) {
            this.id = id;
        }

        private String getTitle() {
            return title;
        }

        private void setTitle(final String title) {
            this.title = title;
        }

        private String getAuthor() {
            return author;
        }

        private void setAuthor(final String author) {
            this.author = author;
        }

        private Integer getCopies() {
            return copies;
        }

        private void setCopies(final Integer copies) {
            this.copies = copies;
        }
    }

    @Entity("authors")
    private static class Author {
        @Id
        private String name;
        private List<String> books;

        private String getName() {
            return name;
        }

        private void setName(final String name) {
            this.name = name;
        }

        private List<String> getBooks() {
            return books;
        }

        private void setBooks(final List<String> books) {
            this.books = books;
        }
    }
}

@@ -1965,17 +1965,9 @@
 ));%0A
-        
 %0A
+
     
@@ -2150,24 +2150,24 @@
 gregate();%0A%0A
-
         Asse
@@ -2229,32 +2229,1524 @@
 ount());%0A    %7D%0A%0A
+    @Test%0A    public void testLimit() %7B%0A        getDs().save(new Book(%22The Banquet%22, %22Dante%22, 2),%0A                     new Book(%22Divine Comedy%22, %22Dante%22, 1),%0A                     new Book(%22Eclogues%22, %22Dante%22, 2),%0A                     new Book(%22The Odyssey%22, %22Homer%22, 10),%0A                     new Book(%22Iliad%22, %22Homer%22, 10));%0A%0A        MorphiaIterator%3CBook, Book%3E aggregate = getDs().createAggregation(Book.class, Book.class)%0A                                                    .limit(2)%0A                                                    .aggregate();%0A        int count = 0;%0A        while (aggregate.hasNext()) %7B%0A            aggregate.next();%0A            count++;%0A        %7D%0A        Assert.assertEquals(2, count);%0A    %7D%0A%0A    @Test%0A    public void testSkip() %7B%0A        getDs().save(new Book(%22The Banquet%22, %22Dante%22, 2),%0A                     new Book(%22Divine Comedy%22, %22Dante%22, 1),%0A                     new Book(%22Eclogues%22, %22Dante%22, 2),%0A                     new Book(%22The Odyssey%22, %22Homer%22, 10),%0A                     new Book(%22Iliad%22, %22Homer%22, 10));%0A%0A        MorphiaIterator%3CBook, Book%3E aggregate = getDs().createAggregation(Book.class, Book.class)%0A                                                    .skip(2)%0A                                                    .aggregate();%0A        Book book = aggregate.next();%0A        Assert.assertEquals(%22Eclogues%22, book.getTitle());%0A        Assert.assertEquals(%22Dante%22, book.getAuthor());%0A        Assert.assertEquals(2, book.getCopies().intValue());%0A    %7D%0A%0A
     @Entity(%22boo

test $limit and $skip