package org.skife.jdbi.v2.sqlobject;

import org.junit.BeforeClass;
import org.junit.Test;
import org.skife.jdbi.v2.DBI;
import org.skife.jdbi.v2.Handle;
import org.skife.jdbi.v2.Something;
import org.skife.jdbi.v2.TransactionIsolationLevel;
import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper;
import org.skife.jdbi.v2.sqlobject.mixins.Transactional;
import org.skife.jdbi.v2.tweak.HandleCallback;
import org.skife.jdbi.v2.util.IntegerMapper;

import java.io.IOException;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeThat;

public class TestPostgresBugs
{
    private static DBI createDbi()
    {
        String user = System.getenv("POSTGRES_USER");
        String pass = System.getenv("POSTGRES_PASS");
        String url = System.getenv("POSTGRES_URL");

        assumeThat(user, notNullValue());
//        assumeThat(pass, notNullValue());
        assumeThat(url, notNullValue());

        org.postgresql.Driver.getVersion();
        return new DBI(url, user, pass);
    }

    @BeforeClass
    public static void setUp() throws Exception
    {
        createDbi().withHandle(new HandleCallback<Object>()
        {
            @Override
            public Object withHandle(Handle handle) throws Exception
            {
                handle.execute("create table if not exists something (id int primary key, name varchar(100))");
                handle.execute("delete from something");
                return null;
            }
        });
    }

    @Test
    public void testConnected() throws Exception
    {
        DBI dbi = createDbi();
        int four = dbi.withHandle(new HandleCallback<Integer>()
        {
            @Override
            public Integer withHandle(Handle handle) throws Exception
            {
                return handle.createQuery("select 2 + 2").map(IntegerMapper.FIRST).first();
            }
        });

        assertThat(four, equalTo(4));
    }

    @Test
    public void testTransactions() throws Exception
    {
        DBI dbi = createDbi();
        Dao dao = dbi.onDemand(Dao.class);

        dao.begin();
        Something s = dao.insertAndFetch(1, "Brian");
        dao.commit();
        assertThat(s, equalTo(new Something(1, "Brian")));
    }


    @RegisterMapper(SomethingMapper.class)
    public static abstract class Dao implements Transactional
    {
        @SqlUpdate("insert into something (id, name) values (:id, :name)")
        public abstract void insert(@Bind("id") int id, @Bind("name") String name);

        @SqlQuery("select id, name from something where id = :id")
        public abstract Something findById(@Bind("id") int id);

        @Transaction(TransactionIsolationLevel.READ_COMMITTED)
        public Something insertAndFetch(int id, String name)
        {
            insert(id, name);
            return findById(id);
        }

        @Transaction
        public Something insertAndFetchWithNestedTransaction(int id, String name)
        {
            return insertAndFetch(id, name);
        }

        @Transaction
        public Something failed(int id, String name) throws IOException
        {
            insert(id, name);
            throw new IOException("woof");
        }
    }
}

@@ -235,16 +235,60 @@
 nLevel;%0A
+import org.skife.jdbi.v2.TransactionStatus;%0A
 import o
@@ -2388,16 +2388,614 @@
 %0A    %7D%0A%0A
+    @Test%0A    public void testExplicitBeginAndInTransaction() throws Exception%0A    %7B%0A        DBI dbi = createDbi();%0A        Dao dao = dbi.onDemand(Dao.class);%0A%0A        dao.begin();%0A        Something s = dao.inTransaction(new org.skife.jdbi.v2.Transaction%3CSomething, Dao%3E() %7B%0A%0A            @Override%0A            public Something inTransaction(Dao transactional, TransactionStatus status) throws Exception%0A            %7B%0A                return  transactional.insertAndFetch(1, %22Brian%22);%0A            %7D%0A        %7D);%0A%0A        dao.commit();%0A        assertThat(s, equalTo(new Something(1, %22Brian%22)));%0A    %7D%0A%0A
 %0A    @Re
@@ -3091,16 +3091,21 @@
 actional
+%3CDao%3E
 %0A    %7B%0A 

test inTrsnaction with explciit