// Path: fluency-core/src/main/java/org/komamitsu/fluency/RetryableException.java
// public class RetryableException
//         extends RuntimeException
// {
//     public RetryableException(String message)
//     {
//         super(message);
//     }
// 
//     public RetryableException(String message, Throwable cause)
//     {
//         super(message, cause);
//     }
// }


import com.google.common.io.ByteStreams;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.komamitsu.fluency.RetryableException;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3ClientBuilder;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPInputStream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
            return null;
        }).when(s3Client).putObject(any(PutObjectRequest.class), any(RequestBody.class));

        AwsS3Sender sender = new AwsS3Sender(s3ClientBuilder, config);

        sender.send("hello.world", "2345/01/31/23/59-59-99999.data",
                ByteBuffer.wrap("0123456789".getBytes(StandardCharsets.UTF_8)));

        verify(s3Client, times(failures + 1)).putObject(any(PutObjectRequest.class), any(RequestBody.class));

        sender.close();
    }

    @ParameterizedTest
    @ValueSource(ints={0, 2})
    void send(int failures)
            throws IOException
    {
        AwsS3Sender.Config config = new AwsS3Sender.Config();
        testSend(config, true, failures);
    }

    @ParameterizedTest
    @ValueSource(ints={0, 2})
    void sendWithoutCompression(int failures)
            throws IOException
    {
        AwsS3Sender.Config config = new AwsS3Sender.Config();
        config.setCompressionEnabled(false);

// Path: fluency-core/src/main/java/org/komamitsu/fluency/RetryableException.java
// public class RetryableException
//         extends RuntimeException
// {
//     public RetryableException(String message)
//     {
//         super(message);
//     }
// 
//     public RetryableException(String message, Throwable cause)
//     {
//         super(message, cause);
//     }
// }


// Path: fluency-aws-s3/src/test/java/org/komamitsu/fluency/aws/s3/ingester/sender/AwsS3SenderTest.java
import com.google.common.io.ByteStreams;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.komamitsu.fluency.RetryableException;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3ClientBuilder;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPInputStream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

            return null;
        }).when(s3Client).putObject(any(PutObjectRequest.class), any(RequestBody.class));

        AwsS3Sender sender = new AwsS3Sender(s3ClientBuilder, config);

        sender.send("hello.world", "2345/01/31/23/59-59-99999.data",
                ByteBuffer.wrap("0123456789".getBytes(StandardCharsets.UTF_8)));

        verify(s3Client, times(failures + 1)).putObject(any(PutObjectRequest.class), any(RequestBody.class));

        sender.close();
    }

    @ParameterizedTest
    @ValueSource(ints={0, 2})
    void send(int failures)
            throws IOException
    {
        AwsS3Sender.Config config = new AwsS3Sender.Config();
        testSend(config, true, failures);
    }

    @ParameterizedTest
    @ValueSource(ints={0, 2})
    void sendWithoutCompression(int failures)
            throws IOException
    {
        AwsS3Sender.Config config = new AwsS3Sender.Config();
        config.setCompressionEnabled(false);

        testSend(config, false, failures);