/*
 * Copyright 2011-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not
 * use this file except in compliance with the License. A copy of the License is
 * located at
 * 
 * http://aws.amazon.com/apache2.0
 * 
 * or in the "license" file accompanying this file. This file 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.
 */
package com.amazonaws.services.s3.waiters;

import com.amazonaws.annotation.SdkInternalApi;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.waiters.*;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AmazonS3Waiters {

    /**
     * Represents the service client
     */
    private final AmazonS3 client;

    private final ExecutorService executorService = Executors
            .newFixedThreadPool(50);

    /**
     * Constructs a new AmazonS3Waiters with the given client
     * 
     * @param client
     *        Service client
     */
    @SdkInternalApi
    public AmazonS3Waiters(AmazonS3 client) {
        this.client = client;
    }

    /**
     * Builds a BucketNotExists waiter by using custom parameters
     * waiterParameters and other parameters defined in the waiters
     * specification, and then polls until it determines whether the resource
     * entered the desired state or not, where polling criteria is bound by
     * either default polling strategy or custom polling strategy.
     */
    public Waiter bucketNotExists() {

        return new WaiterBuilder<HeadBucketRequest, HeadBucketResult>()
                .withSdkFunction(new HeadBucketFunction(client))
                .withAcceptors(
                        new HttpFailureStatusAcceptor(404, WaiterState.SUCCESS))
                .withDefaultPollingStrategy(
                        new PollingStrategy(new MaxAttemptsRetryStrategy(20),
                                new FixedDelayStrategy(5)))
                .withExecutorService(executorService).build();
    }

    /**
     * Builds a BucketExists waiter by using custom parameters waiterParameters
     * and other parameters defined in the waiters specification, and then polls
     * until it determines whether the resource entered the desired state or
     * not, where polling criteria is bound by either default polling strategy
     * or custom polling strategy.
     */
    public Waiter bucketExists() {

        return new WaiterBuilder<HeadBucketRequest, HeadBucketResult>()
                .withSdkFunction(new HeadBucketFunction(client))
                .withAcceptors(
                        new HttpSuccessStatusAcceptor(WaiterState.SUCCESS),
                        new HttpFailureStatusAcceptor(301, WaiterState.SUCCESS),
                        new HttpFailureStatusAcceptor(403, WaiterState.SUCCESS),
                        new HttpFailureStatusAcceptor(404, WaiterState.RETRY))
                .withDefaultPollingStrategy(
                        new PollingStrategy(new MaxAttemptsRetryStrategy(20),
                                new FixedDelayStrategy(5)))
                .withExecutorService(executorService).build();
    }

    /**
     * Builds a ObjectExists waiter by using custom parameters waiterParameters
     * and other parameters defined in the waiters specification, and then polls
     * until it determines whether the resource entered the desired state or
     * not, where polling criteria is bound by either default polling strategy
     * or custom polling strategy.
     */
    public Waiter objectExists() {

        return new WaiterBuilder<GetObjectMetadataRequest, ObjectMetadata>()
                .withSdkFunction(new HeadObjectFunction(client))
                .withAcceptors(
                        new HttpSuccessStatusAcceptor(WaiterState.SUCCESS),
                        new HttpFailureStatusAcceptor(404, WaiterState.RETRY))
                .withDefaultPollingStrategy(
                        new PollingStrategy(new MaxAttemptsRetryStrategy(20),
                                new FixedDelayStrategy(5)))
                .withExecutorService(executorService).build();
    }

    /**
     * Builds a ObjectNotExists waiter by using custom parameters
     * waiterParameters and other parameters defined in the waiters
     * specification, and then polls until it determines whether the resource
     * entered the desired state or not, where polling criteria is bound by
     * either default polling strategy or custom polling strategy.
     */
    public Waiter objectNotExists() {

        return new WaiterBuilder<GetObjectMetadataRequest, ObjectMetadata>()
                .withSdkFunction(new HeadObjectFunction(client))
                .withAcceptors(
                        new HttpFailureStatusAcceptor(404, WaiterState.SUCCESS))
                .withDefaultPollingStrategy(
                        new PollingStrategy(new MaxAttemptsRetryStrategy(20),
                                new FixedDelayStrategy(5)))
                .withExecutorService(executorService).build();
    }

}

@@ -1719,24 +1719,43 @@
 ublic Waiter
+%3CHeadBucketRequest%3E
  bucketNotEx
@@ -1755,32 +1755,32 @@
 etNotExists() %7B%0A
-
 %0A        return 
@@ -1978,32 +1978,50 @@
 reStatusAcceptor
+%3CHeadBucketResult%3E
 (404, WaiterStat
@@ -2670,16 +2670,35 @@
 c Waiter
+%3CHeadBucketRequest%3E
  bucketE
@@ -2922,32 +2922,50 @@
 ssStatusAcceptor
+%3CHeadBucketResult%3E
 (WaiterState.SUC
@@ -3024,16 +3024,34 @@
 Acceptor
+%3CHeadBucketResult%3E
 (301, Wa
@@ -3123,16 +3123,34 @@
 Acceptor
+%3CHeadBucketResult%3E
 (403, Wa
@@ -3214,32 +3214,50 @@
 reStatusAcceptor
+%3CHeadBucketResult%3E
 (404, WaiterStat
@@ -3900,24 +3900,50 @@
 ublic Waiter
+%3CGetObjectMetadataRequest%3E
  objectExist
@@ -4176,16 +4176,32 @@
 Acceptor
+%3CObjectMetadata%3E
 (WaiterS
@@ -4260,32 +4260,48 @@
 reStatusAcceptor
+%3CObjectMetadata%3E
 (404, WaiterStat
@@ -4951,16 +4951,42 @@
 c Waiter
+%3CGetObjectMetadataRequest%3E
  objectN
@@ -5165,32 +5165,32 @@
 .withAcceptors(%0A
-
                 
@@ -5226,16 +5226,32 @@
 Acceptor
+%3CObjectMetadata%3E
 (404, Wa

Fix generic types on Return type for s3 waiters (#1639)