package io.vertx.pgclient.data;

import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.pgclient.PgConnection;
import io.vertx.sqlclient.Row;
import io.vertx.sqlclient.Tuple;
import org.junit.Test;

public class TsTypesExtendedCodecTest extends ExtendedQueryDataTypeCodecTestBase {

  @Test
  public void test_tsquery_and_tsvector(TestContext ctx) {
    Async async = ctx.async();
    PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
      conn.prepare("SELECT to_tsvector( $1 ) @@ to_tsquery( $2 ) as \"TsQuery\"",
        ctx.asyncAssertSuccess(p -> {
          p.execute(Tuple.tuple()
            .addString("postgraduate")
            .addString("postgres:*"), ctx.asyncAssertSuccess(result -> {
            ctx.assertEquals(1, result.size());
            ctx.assertEquals(1, result.rowCount());
            Row row = result.iterator().next();
            ColumnChecker.checkColumn(0, "TsQuery")
              .returns(Tuple::getBoolean, Row::getBoolean, Boolean.TRUE)
              .returns(Tuple::getValue, Row::getValue, Boolean.TRUE)
              .forRow(row);
            async.complete();
          }));
        }));
    }));
  }

  @Test
  public void test_tsvector(TestContext ctx) {
    Async async = ctx.async();
    PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
      conn.prepare("SELECT c \"TsVector\" FROM ( VALUES ( to_tsvector ( $1 ) )) as t (c)",
        ctx.asyncAssertSuccess(p -> {
          p.execute(Tuple.tuple()
            .addString("postgraduate"), ctx.asyncAssertSuccess(result -> {
            ctx.assertEquals(1, result.size());
            ctx.assertEquals(1, result.rowCount());
            Row row = result.iterator().next();
            String expected = "'postgradu':1";
            ColumnChecker.checkColumn(0, "TsVector")
              .returns(Tuple::getString, Row::getString, expected)
              .returns(Tuple::getValue, Row::getValue, expected)
              .forRow(row);
            async.complete();
          }));
        }));
    }));
  }

  @Test
  public void test_tsvector_array(TestContext ctx) {
    Async async = ctx.async();
    PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
      conn.prepare("SELECT c \"TsVector\" FROM ( VALUES ( ARRAY[to_tsvector ( $1 ), to_tsvector ( $2 )] )) as t (c) GROUP BY c",
        ctx.asyncAssertSuccess(p -> {
          p.execute(Tuple.tuple()
            .addString("postgraduate")
            .addString("a fat cat sat on a mat and ate a fat rat"), ctx.asyncAssertSuccess(result -> {
            ctx.assertEquals(1, result.size());
            ctx.assertEquals(1, result.rowCount());
            Row row = result.iterator().next();
            String[] expected = new String[]{"'postgradu':1", "'ate':9 'cat':3 'fat':2,11 'mat':7 'rat':12 'sat':4"};
            ColumnChecker.checkColumn(0, "TsVector")
              .returns(Tuple::getStringArray, Row::getStringArray, expected)
              .returns(Tuple::getValue, Row::getValue, expected)
              .forRow(row);
            async.complete();
          }));
        }));
    }));
  }


  @Test
  public void test_tsquery(TestContext ctx) {
    Async async = ctx.async();
    PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
      conn.prepare("SELECT c \"TsQuery\" FROM ( VALUES ( to_tsquery ( $1 ) )) as t (c)",
        ctx.asyncAssertSuccess(p -> {
          p.execute(Tuple.tuple()
            .addString("Fat:ab & Cats"), ctx.asyncAssertSuccess(result -> {
            ctx.assertEquals(1, result.size());
            ctx.assertEquals(1, result.rowCount());
            Row row = result.iterator().next();
            String expected = "'fat':AB & 'cat'";
            ColumnChecker.checkColumn(0, "TsQuery")
              .returns(Tuple::getString, Row::getString, expected)
              .returns(Tuple::getValue, Row::getValue, expected)
              .forRow(row);
            async.complete();
          }));
        }));
    }));
  }

  @Test
  public void test_tsquery_array(TestContext ctx) {
    Async async = ctx.async();
    PgConnection.connect(vertx, options, ctx.asyncAssertSuccess(conn -> {
      conn.prepare("SELECT c \"TsQuery\" FROM ( VALUES ( ARRAY[to_tsquery ( $1 ), to_tsquery ( $2 )] )) as t (c)",
        ctx.asyncAssertSuccess(p -> {
          p.execute(Tuple.tuple()
            .addString("Fat:ab & Cats")
            .addString("super:*"), ctx.asyncAssertSuccess(result -> {
            ctx.assertEquals(1, result.size());
            ctx.assertEquals(1, result.rowCount());
            Row row = result.iterator().next();
            String[] expected = new String[]{"'fat':AB & 'cat'", "'super':*"};
            ColumnChecker.checkColumn(0, "TsQuery")
              .returns(Tuple::getStringArray, Row::getStringArray, expected)
              .returns(Tuple::getValue, Row::getValue, expected)
              .forRow(row);
            async.complete();
          }));
        }));
    }));
  }

}

@@ -518,16 +518,26 @@
 svector(
+'english',
  $1 ) @@
@@ -548,16 +548,26 @@
 tsquery(
+'english',
  $2 ) as
@@ -1434,24 +1434,34 @@
 o_tsvector (
+'english',
  $1 ) )) as 
@@ -2338,16 +2338,26 @@
 vector (
+'english',
  $1 ), t
@@ -2368,16 +2368,26 @@
 vector (
+'english',
  $2 )%5D )
@@ -3410,24 +3410,34 @@
 to_tsquery (
+'english',
  $1 ) )) as 
@@ -4314,16 +4314,26 @@
 squery (
+'english',
  $1 ), t
@@ -4343,16 +4343,26 @@
 squery (
+'english',
  $2 )%5D )

Fix inconsistency in text search tests (#373)