package com.smbtec.xo.orientdb.test.query;

import java.net.URISyntaxException;
import java.util.Collection;

import org.hamcrest.collection.IsIterableContainingInAnyOrder;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import com.buschmais.xo.api.CompositeObject;
import com.buschmais.xo.api.Example;
import com.buschmais.xo.api.XOException;
import com.buschmais.xo.api.Query.Result;
import com.buschmais.xo.api.Query.Result.CompositeRowObject;
import com.buschmais.xo.api.XOManager;
import com.buschmais.xo.api.bootstrap.XOUnit;
import com.smbtec.xo.orientdb.test.AbstractOrientDbXOManagerTest;
import com.smbtec.xo.orientdb.test.query.composite.Person;

import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;

@RunWith(Parameterized.class)
public class SqlQueryTest extends AbstractOrientDbXOManagerTest {

    private Person john;
    private Person mary;
    private Person jDow;

    public SqlQueryTest(XOUnit xoUnit) {
        super(xoUnit);
    }

    @Parameterized.Parameters
    public static Collection<Object[]> getXOUnits() throws URISyntaxException {
        return xoUnits(Person.class);
    }

    @Before
    public void populate() {
        XOManager xoManager = getXoManager();
        xoManager.currentTransaction().begin();
        john = xoManager.create(new Example<Person>() {

            @Override
            public void prepare(Person example) {
                example.setFirstname("John");
                example.setLastname("Doe");
                example.setAge(25);
            }

        }, Person.class);
        mary = xoManager.create(new Example<Person>() {

            @Override
            public void prepare(Person example) {
                example.setFirstname("Mary");
                example.setLastname("Doe");
                example.setAge(20);
            }

        }, Person.class);

        jDow = xoManager.create(new Example<Person>() {

            @Override
            public void prepare(Person example) {
                example.setFirstname("Jon");
                example.setLastname("Dow");
                example.setAge(31);
            }

        }, Person.class);
        john.getFriends().add(mary);
        john.getFriends().add(jDow);
        xoManager.currentTransaction().commit();
    }

    @Test
    public void selectVertexById() {
        XOManager xoManager = getXoManager();
        xoManager.currentTransaction().begin();
        Object id = ((CompositeObject) john).getId();
        Person person = xoManager
                .createQuery("SELECT FROM [" + id + "]", Person.class)
                .execute().getSingleResult();
        assertThat(person, equalTo(john));
        xoManager.currentTransaction().commit();
    }

    @Test
    public void countVerticesWithGivenField() {
        XOManager xoManager = getXoManager();
        xoManager.currentTransaction().begin();
        Long count = xoManager
                .createQuery("SELECT count(*) FROM V WHERE firstname = 'John'",
                        Long.class).execute().getSingleResult();
        assertThat(count, equalTo(1L));
        xoManager.currentTransaction().commit();

    }

    @Test
    public void selectOutEdgesFromVertex() {
        XOManager xoManager = getXoManager();
        xoManager.currentTransaction().begin();
        Result<CompositeRowObject> result = xoManager.createQuery(
                "SELECT outE() FROM V WHERE firstname = 'John'").execute();
        assertThat(result.hasResult(), is(true));
        xoManager.currentTransaction().commit();
    }

    @Test
    public void countOutEdgesFromVertexWithGivenField() {
        XOManager xoManager = getXoManager();
        xoManager.currentTransaction().begin();
        Object id = ((CompositeObject) john).getId();
        Integer count = xoManager
                .createQuery("SELECT out().size() FROM [" + id + "]",
                        Integer.class).execute().getSingleResult();
        assertThat(count, equalTo(2));
        xoManager.currentTransaction().commit();
    }

    @Test
    public void selectAllVertices() {
        XOManager xoManager = getXoManager();
        xoManager.currentTransaction().begin();
        Result<Person> result = xoManager.createQuery("SELECT FROM V", Person.class).execute();
        assertThat(result, IsIterableContainingInAnyOrder.<Person>containsInAnyOrder(john, mary, jDow));
        xoManager.currentTransaction().commit();
    }
}

@@ -37,16 +37,145 @@
 query;%0A%0A
+import static org.hamcrest.Matchers.equalTo;%0Aimport static org.hamcrest.Matchers.is;%0Aimport static org.junit.Assert.assertThat;%0A%0A
 import j
@@ -198,24 +198,24 @@
 xException;%0A
-
 import java.
@@ -528,49 +528,8 @@
 le;%0A
-import com.buschmais.xo.api.XOException;%0A
 impo
@@ -842,137 +842,8 @@
 n;%0A%0A
-import static org.junit.Assert.assertThat;%0Aimport static org.hamcrest.Matchers.equalTo;%0Aimport static org.hamcrest.Matchers.is;%0A%0A
 @Run
@@ -2618,33 +2618,16 @@
 oManager
-%0A                
 .createQ
@@ -2672,33 +2672,16 @@
 n.class)
-%0A                
 .execute
@@ -2983,33 +2983,16 @@
 oManager
-%0A                
 .createQ
@@ -3050,32 +3050,8 @@
 n'%22,
-%0A                       
  Lon
@@ -3060,32 +3060,49 @@
 class).execute()
+%0A                
 .getSingleResult
@@ -3417,33 +3417,16 @@
 teQuery(
-%0A                
 %22SELECT 
@@ -3465,16 +3465,33 @@
 'John'%22)
+%0A                
 .execute
@@ -3849,33 +3849,16 @@
 oManager
-%0A                
 .createQ
@@ -3906,32 +3906,8 @@
 %22%5D%22,
-%0A                       
  Int
@@ -3919,32 +3919,49 @@
 class).execute()
+%0A                
 .getSingleResult
@@ -4363,16 +4363,17 @@
 %3CPerson%3E
+ 
 contains
@@ -4457,11 +4457,409 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void selectTypedVertex() %7B%0A        XOManager xoManager = getXoManager();%0A        xoManager.currentTransaction().begin();%0A        Person person = xoManager.createQuery(%22SELECT FROM Person WHERE firstname = 'John'%22, Person.class).execute()%0A                .getSingleResult();%0A        assertThat(person, is(equalTo(john)));%0A        xoManager.currentTransaction().commit();%0A    %7D
 %0A%7D%0A

add typed query test