// Path: src/main/java/org/lmdbjava/ByteArrayProxy.java
// public static final BufferProxy<byte[]> PROXY_BA = new ByteArrayProxy();
// 
// Path: src/main/java/org/lmdbjava/ByteBufProxy.java
// public static final BufferProxy<ByteBuf> PROXY_NETTY = new ByteBufProxy();
// 
// Path: src/main/java/org/lmdbjava/ByteBufferProxy.java
// public static final BufferProxy<ByteBuffer> PROXY_OPTIMAL;
// 
// Path: src/main/java/org/lmdbjava/ByteBufferProxy.java
// public static final BufferProxy<ByteBuffer> PROXY_SAFE;
// 
// Path: src/main/java/org/lmdbjava/DirectBufferProxy.java
// public static final BufferProxy<DirectBuffer> PROXY_DB
//     = new DirectBufferProxy();
// 
// Path: src/main/java/org/lmdbjava/Env.java
// public static Builder<ByteBuffer> create() {
//   return new Builder<>(PROXY_OPTIMAL);
// }
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// public static final String DB_1 = "test-db-1";
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// @SuppressWarnings("PMD.AvoidUsingOctalValues")
// public static final int POSIX_MODE = 0664;
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// static ByteBuffer bb(final int value) {
//   final ByteBuffer bb = allocateDirect(BYTES);
//   bb.putInt(value).flip();
//   return bb;
// }
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// static MutableDirectBuffer mdb(final int value) {
//   final MutableDirectBuffer b = new UnsafeBuffer(allocateDirect(BYTES));
//   b.putInt(0, value);
//   return b;
// }
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// static ByteBuf nb(final int value) {
//   final ByteBuf b = DEFAULT.directBuffer(BYTES);
//   b.writeInt(value);
//   return b;
// }


import static com.jakewharton.byteunits.BinaryByteUnit.KIBIBYTES;
import static java.lang.Long.BYTES;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsEmptyCollection.empty;
import static org.lmdbjava.ByteArrayProxy.PROXY_BA;
import static org.lmdbjava.ByteBufProxy.PROXY_NETTY;
import static org.lmdbjava.ByteBufferProxy.PROXY_OPTIMAL;
import static org.lmdbjava.ByteBufferProxy.PROXY_SAFE;
import static org.lmdbjava.DbiFlags.MDB_CREATE;
import static org.lmdbjava.DbiFlags.MDB_DUPSORT;
import static org.lmdbjava.DirectBufferProxy.PROXY_DB;
import static org.lmdbjava.Env.create;
import static org.lmdbjava.EnvFlags.MDB_NOSUBDIR;
import static org.lmdbjava.GetOp.MDB_SET_KEY;
import static org.lmdbjava.GetOp.MDB_SET_RANGE;
import static org.lmdbjava.PutFlags.MDB_NOOVERWRITE;
import static org.lmdbjava.SeekOp.MDB_FIRST;
import static org.lmdbjava.SeekOp.MDB_LAST;
import static org.lmdbjava.SeekOp.MDB_NEXT;
import static org.lmdbjava.SeekOp.MDB_PREV;
import static org.lmdbjava.TestUtils.DB_1;
import static org.lmdbjava.TestUtils.POSIX_MODE;
import static org.lmdbjava.TestUtils.bb;
import static org.lmdbjava.TestUtils.mdb;
import static org.lmdbjava.TestUtils.nb;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import io.netty.buffer.ByteBuf;
import org.agrona.DirectBuffer;
import org.agrona.MutableDirectBuffer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
/*-
 * #%L
 * LmdbJava
 * %%
 * Copyright (C) 2016 - 2021 The LmdbJava Open Source Project
 * %%
 * 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.
 * #L%
 */

package org.lmdbjava;




/**
 * Test {@link Cursor} with different buffer implementations.
 */
@RunWith(Parameterized.class)
public final class CursorParamTest {

  /**
   * Injected by {@link #data()} with appropriate runner.
   */
  @Parameter
  public BufferRunner<?> runner;

  @Rule
  public final TemporaryFolder tmp = new TemporaryFolder();

  @Parameters(name = "{index}: buffer adapter: {0}")
  public static Object[] data() {
    final BufferRunner<ByteBuffer> bb1 = new ByteBufferRunner(PROXY_OPTIMAL);
    final BufferRunner<ByteBuffer> bb2 = new ByteBufferRunner(PROXY_SAFE);
    final BufferRunner<byte[]> ba = new ByteArrayRunner(PROXY_BA);
    final BufferRunner<DirectBuffer> db = new DirectBufferRunner();
    final BufferRunner<ByteBuf> netty = new NettyBufferRunner();
    return new Object[]{bb1, bb2, ba, db, netty};
  }

  @Test
  public void execute() {
    runner.execute(tmp);
  }

  /**
   * Abstract implementation of {@link BufferRunner}.
   *
   * @param <T> buffer type
   */
  private abstract static class AbstractBufferRunner<T> implements
      BufferRunner<T> {

    final BufferProxy<T> proxy;

    protected AbstractBufferRunner(final BufferProxy<T> proxy) {
      this.proxy = proxy;
    }

    @Override
    public final void execute(final TemporaryFolder tmp) {
      try (Env<T> env = env(tmp)) {
        assertThat(env.getDbiNames(), empty());
// Path: src/main/java/org/lmdbjava/ByteArrayProxy.java
// public static final BufferProxy<byte[]> PROXY_BA = new ByteArrayProxy();
// 
// Path: src/main/java/org/lmdbjava/ByteBufProxy.java
// public static final BufferProxy<ByteBuf> PROXY_NETTY = new ByteBufProxy();
// 
// Path: src/main/java/org/lmdbjava/ByteBufferProxy.java
// public static final BufferProxy<ByteBuffer> PROXY_OPTIMAL;
// 
// Path: src/main/java/org/lmdbjava/ByteBufferProxy.java
// public static final BufferProxy<ByteBuffer> PROXY_SAFE;
// 
// Path: src/main/java/org/lmdbjava/DirectBufferProxy.java
// public static final BufferProxy<DirectBuffer> PROXY_DB
//     = new DirectBufferProxy();
// 
// Path: src/main/java/org/lmdbjava/Env.java
// public static Builder<ByteBuffer> create() {
//   return new Builder<>(PROXY_OPTIMAL);
// }
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// public static final String DB_1 = "test-db-1";
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// @SuppressWarnings("PMD.AvoidUsingOctalValues")
// public static final int POSIX_MODE = 0664;
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// static ByteBuffer bb(final int value) {
//   final ByteBuffer bb = allocateDirect(BYTES);
//   bb.putInt(value).flip();
//   return bb;
// }
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// static MutableDirectBuffer mdb(final int value) {
//   final MutableDirectBuffer b = new UnsafeBuffer(allocateDirect(BYTES));
//   b.putInt(0, value);
//   return b;
// }
// 
// Path: src/test/java/org/lmdbjava/TestUtils.java
// static ByteBuf nb(final int value) {
//   final ByteBuf b = DEFAULT.directBuffer(BYTES);
//   b.writeInt(value);
//   return b;
// }


// Path: src/test/java/org/lmdbjava/CursorParamTest.java
import static com.jakewharton.byteunits.BinaryByteUnit.KIBIBYTES;
import static java.lang.Long.BYTES;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.collection.IsEmptyCollection.empty;
import static org.lmdbjava.ByteArrayProxy.PROXY_BA;
import static org.lmdbjava.ByteBufProxy.PROXY_NETTY;
import static org.lmdbjava.ByteBufferProxy.PROXY_OPTIMAL;
import static org.lmdbjava.ByteBufferProxy.PROXY_SAFE;
import static org.lmdbjava.DbiFlags.MDB_CREATE;
import static org.lmdbjava.DbiFlags.MDB_DUPSORT;
import static org.lmdbjava.DirectBufferProxy.PROXY_DB;
import static org.lmdbjava.Env.create;
import static org.lmdbjava.EnvFlags.MDB_NOSUBDIR;
import static org.lmdbjava.GetOp.MDB_SET_KEY;
import static org.lmdbjava.GetOp.MDB_SET_RANGE;
import static org.lmdbjava.PutFlags.MDB_NOOVERWRITE;
import static org.lmdbjava.SeekOp.MDB_FIRST;
import static org.lmdbjava.SeekOp.MDB_LAST;
import static org.lmdbjava.SeekOp.MDB_NEXT;
import static org.lmdbjava.SeekOp.MDB_PREV;
import static org.lmdbjava.TestUtils.DB_1;
import static org.lmdbjava.TestUtils.POSIX_MODE;
import static org.lmdbjava.TestUtils.bb;
import static org.lmdbjava.TestUtils.mdb;
import static org.lmdbjava.TestUtils.nb;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import io.netty.buffer.ByteBuf;
import org.agrona.DirectBuffer;
import org.agrona.MutableDirectBuffer;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

/*-
 * #%L
 * LmdbJava
 * %%
 * Copyright (C) 2016 - 2021 The LmdbJava Open Source Project
 * %%
 * 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.
 * #L%
 */

package org.lmdbjava;




/**
 * Test {@link Cursor} with different buffer implementations.
 */
@RunWith(Parameterized.class)
public final class CursorParamTest {

  /**
   * Injected by {@link #data()} with appropriate runner.
   */
  @Parameter
  public BufferRunner<?> runner;

  @Rule
  public final TemporaryFolder tmp = new TemporaryFolder();

  @Parameters(name = "{index}: buffer adapter: {0}")
  public static Object[] data() {
    final BufferRunner<ByteBuffer> bb1 = new ByteBufferRunner(PROXY_OPTIMAL);
    final BufferRunner<ByteBuffer> bb2 = new ByteBufferRunner(PROXY_SAFE);
    final BufferRunner<byte[]> ba = new ByteArrayRunner(PROXY_BA);
    final BufferRunner<DirectBuffer> db = new DirectBufferRunner();
    final BufferRunner<ByteBuf> netty = new NettyBufferRunner();
    return new Object[]{bb1, bb2, ba, db, netty};
  }

  @Test
  public void execute() {
    runner.execute(tmp);
  }

  /**
   * Abstract implementation of {@link BufferRunner}.
   *
   * @param <T> buffer type
   */
  private abstract static class AbstractBufferRunner<T> implements
      BufferRunner<T> {

    final BufferProxy<T> proxy;

    protected AbstractBufferRunner(final BufferProxy<T> proxy) {
      this.proxy = proxy;
    }

    @Override
    public final void execute(final TemporaryFolder tmp) {
      try (Env<T> env = env(tmp)) {
        assertThat(env.getDbiNames(), empty());
        final Dbi<T> db = env.openDbi(DB_1, MDB_CREATE, MDB_DUPSORT);