// Path: src/main/java/uk/co/visalia/brightpearl/apiclient/http/ClientFactory.java
// public interface ClientFactory {
// 
//     /**
//      * <p>
//      * Get a client to be used for a given {@link uk.co.visalia.brightpearl.apiclient.account.Account}. This method will be called
//      * for every request to be made to the Brightpearl API, so that client instances that support only a single request
//      * are supported. Implementations may return the same instance in response to multiple calls to this method, and
//      * should do so provided the client is thread-safe and supports multiple concurrent requests.
//      * </p><p>
//      * Creating a client for each customer account is not recommended but can be used as a method of throttling the
//      * resources available to each account, so the account is included as a parameter to allow this.
//      * </p>
//      * @param account The Brightpearl customer account a client is required for.
//      * @return A client instance appropriate for the account.
//      */
//     Client getClient(Account account);
// 
// }
// 
// Path: src/main/java/uk/co/visalia/brightpearl/apiclient/ratelimit/RateLimiter.java
// public interface RateLimiter {
// 
//     /**
//      * Called immediately before a request is made to the Brightpearl API for the given account. Implementations may
//      * sleep before returning to reduce throughput, or throw an exception to abort the request.
//      * @param account The account a request will be sent to.
//      */
//     void rateLimit(Account account);
// 
//     /**
//      * Called after every request is made to the Brightpearl API, with values from the brightpearl-requests-remaining
//      * and brightpearl-next-throttle-period headers. These may be used to adjust the behaviour of the {@link #rateLimit(Account)}
//      * method, but as other requests may have been made on other threads while this request was executing, the values
//      * may be stale, and events may be received out of sequence.
//      * @param account The account a response has been received from.
//      * @param requestsRemaining The value of the brightpearl-requests-remaining response header.
//      * @param nextThrottlePeriod The value of the brightpearl-next-throttle-period header.
//      */
//     void requestCompleted(Account account, int requestsRemaining, long nextThrottlePeriod);
// 
//     /**
//      * Called when a request to an account has been rejected due to request throttling. This event may be used to adjust
//      * the behaviour of the the {@link #rateLimit(Account)} method. Other concurrent requests that were already started
//      * at the time this event is received are likely to also fail.
//      * @param account An account for which a request cap error has been received.
//      */
//     void requestCapExceeded(Account account);
// 
// }


import com.google.gson.Gson;
import uk.co.visalia.brightpearl.apiclient.http.ClientFactory;
import uk.co.visalia.brightpearl.apiclient.ratelimit.RateLimiter;
import java.util.Calendar;
/*
 * Copyright 2014 David Morrissey
 *
 * 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.
 */

package uk.co.visalia.brightpearl.apiclient;



/**
 * <p>
 * Constructs a configured {@link BrightpearlApiClient}. Supports construction in code using the builder pattern (starting
 * with {@link #brightpearlApiClient()}) and usage as a Spring bean factory. For example:
 * </p>
 * <pre>
 * &lt;bean id="brightpearlApiClientFactory" class="BrightpearlApiClientFactory"&gt;
 *     &lt;property name="clientFactory" ref="myClientFactory"/&gt;
 * &lt;/bean&gt;
 *
 * &lt;bean id="brightpearlApiClient"
 *     factory-bean="brightpearlApiClientFactory"
 *     factory-method="build"/&gt;
 * </pre>
 * <p>
 * Defaults are available for all the configuration options so there is no requirement to set any options before building
 * the client instance.
 * </p>
 */
public final class BrightpearlApiClientFactory {

    private ClientFactory clientFactory;
// Path: src/main/java/uk/co/visalia/brightpearl/apiclient/http/ClientFactory.java
// public interface ClientFactory {
// 
//     /**
//      * <p>
//      * Get a client to be used for a given {@link uk.co.visalia.brightpearl.apiclient.account.Account}. This method will be called
//      * for every request to be made to the Brightpearl API, so that client instances that support only a single request
//      * are supported. Implementations may return the same instance in response to multiple calls to this method, and
//      * should do so provided the client is thread-safe and supports multiple concurrent requests.
//      * </p><p>
//      * Creating a client for each customer account is not recommended but can be used as a method of throttling the
//      * resources available to each account, so the account is included as a parameter to allow this.
//      * </p>
//      * @param account The Brightpearl customer account a client is required for.
//      * @return A client instance appropriate for the account.
//      */
//     Client getClient(Account account);
// 
// }
// 
// Path: src/main/java/uk/co/visalia/brightpearl/apiclient/ratelimit/RateLimiter.java
// public interface RateLimiter {
// 
//     /**
//      * Called immediately before a request is made to the Brightpearl API for the given account. Implementations may
//      * sleep before returning to reduce throughput, or throw an exception to abort the request.
//      * @param account The account a request will be sent to.
//      */
//     void rateLimit(Account account);
// 
//     /**
//      * Called after every request is made to the Brightpearl API, with values from the brightpearl-requests-remaining
//      * and brightpearl-next-throttle-period headers. These may be used to adjust the behaviour of the {@link #rateLimit(Account)}
//      * method, but as other requests may have been made on other threads while this request was executing, the values
//      * may be stale, and events may be received out of sequence.
//      * @param account The account a response has been received from.
//      * @param requestsRemaining The value of the brightpearl-requests-remaining response header.
//      * @param nextThrottlePeriod The value of the brightpearl-next-throttle-period header.
//      */
//     void requestCompleted(Account account, int requestsRemaining, long nextThrottlePeriod);
// 
//     /**
//      * Called when a request to an account has been rejected due to request throttling. This event may be used to adjust
//      * the behaviour of the the {@link #rateLimit(Account)} method. Other concurrent requests that were already started
//      * at the time this event is received are likely to also fail.
//      * @param account An account for which a request cap error has been received.
//      */
//     void requestCapExceeded(Account account);
// 
// }


// Path: src/main/java/uk/co/visalia/brightpearl/apiclient/BrightpearlApiClientFactory.java
import com.google.gson.Gson;
import uk.co.visalia.brightpearl.apiclient.http.ClientFactory;
import uk.co.visalia.brightpearl.apiclient.ratelimit.RateLimiter;
import java.util.Calendar;

/*
 * Copyright 2014 David Morrissey
 *
 * 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.
 */

package uk.co.visalia.brightpearl.apiclient;



/**
 * <p>
 * Constructs a configured {@link BrightpearlApiClient}. Supports construction in code using the builder pattern (starting
 * with {@link #brightpearlApiClient()}) and usage as a Spring bean factory. For example:
 * </p>
 * <pre>
 * &lt;bean id="brightpearlApiClientFactory" class="BrightpearlApiClientFactory"&gt;
 *     &lt;property name="clientFactory" ref="myClientFactory"/&gt;
 * &lt;/bean&gt;
 *
 * &lt;bean id="brightpearlApiClient"
 *     factory-bean="brightpearlApiClientFactory"
 *     factory-method="build"/&gt;
 * </pre>
 * <p>
 * Defaults are available for all the configuration options so there is no requirement to set any options before building
 * the client instance.
 * </p>
 */
public final class BrightpearlApiClientFactory {

    private ClientFactory clientFactory;
    private RateLimiter rateLimiter;