// Path: GroundControl/groundcontrol/src/main/java/com/bottlerocketstudios/groundcontrol/agent/Agent.java
// public interface Agent<ResultType, ProgressType> extends Runnable {
//     /**
//      * Provide a globally unique string to identify this agent. All identical agents will
//      * be executed one at a time. If available, cached values for Agents with the same unique
//      * identifier will be delivered.
//      */
//     String getUniqueIdentifier();
// 
//     /**
//      * Stop executing ASAP, your result is no longer needed. If this is a meta-Agent cancel any
//      * associated AgentTethers you have created. This will also be called after cancelTimeoutMs
//      * has elapsed.
//      */
//     void cancel();
// 
//     /**
//      * Maximum amount of time in milliseconds to allow an Agent's run operation to run before being interrupted.
//      * Using a very large number with a repeated task that fails to complete may result in exhausted Thread
//      * pool. Must be greater than getCancelTimeoutMs(). <strong>This value will be read before execution.</strong>
//      */
//     long getRunTimeoutMs();
// 
//     /**
//      * Maximum amount of time in milliseconds starting at run() before cancel() is called if incomplete.
//      * <strong>This value will be read before execution.</strong>
//      */
//     long getCancelTimeoutMs();
// 
//     /**
//      * Maximum amount of time in milliseconds starting at run() to being discarded even if incomplete. Must be
//      * greater than getCancelTimeoutMs() and getRunTimeoutMs(). <strong>This value will be read before execution.</strong>
//      */
//     long getMaximumTimeoutMs();
// 
//     /**
//      * Set the listener for the agent. This listener must be called when the agent has completed or has
//      * progress to deliver.
//      */
//     void setAgentListener(AgentListener<ResultType, ProgressType> agentListener);
// 
//     /**
//      * Set the agentExecutor that will be running this agent. This is guaranteed to be populated before run().
//      * This should be used to spawn further Agent executions and ensures that an Agent could be used with
//      * multiple executors and not be tightly coupled to any specific instance.
//      *
//      * <p><strong>You must not perform work in this operation other than storing the reference.</strong></p>
//      */
//     void setAgentExecutor(AgentExecutor agentExecutor);
// 
//     /**
//      * At the Agent's next convenience, deliver a progress update if applicable. This will be called when
//      * an already running Agent has a new AgentRequest queued.
//      */
//     void onProgressUpdateRequested();
// }
// 
// Path: GroundControl/groundcontrol/src/main/java/com/bottlerocketstudios/groundcontrol/listener/AgentListener.java
// public interface AgentListener<ResultType, ProgressType> {
//     /**
//      * Request has been completed with the associated result value.
//      */
//     void onCompletion(String agentIdentifier, ResultType result);
// 
//     /**
//      * Request is still in progress and provided an update.
//      */
//     void onProgress(String agentIdentifier, ProgressType progress);
// }
// 
// Path: GroundControl/groundcontrol/src/main/java/com/bottlerocketstudios/groundcontrol/policy/AgentPolicy.java
// public class AgentPolicy {
//     private final String mCallbackLooperId;
//     private final long mPolicyTimeoutMs;
//     private final long mParallelCallbackTimeoutMs;
//     private final long mMaxCacheAgeMs;
//     private final JobPriority mJobPriority;
//     private final boolean mParallelBackgroundCallback;
//     private final boolean mBypassCache;
//     private final boolean mClearCache;
// 
//     public AgentPolicy(AgentPolicyBuilder builder) {
//         mCallbackLooperId = builder.getCallbackLooperId();
//         mPolicyTimeoutMs = builder.getPolicyTimeoutMs();
//         mMaxCacheAgeMs = builder.getMaxCacheAgeMs();
//         mJobPriority = builder.getJobPriority();
//         mParallelBackgroundCallback = builder.isParallelBackgroundCallback();
//         mBypassCache = builder.shouldBypassCache();
//         mParallelCallbackTimeoutMs = builder.getParallelCallbackTimeoutMs();
//         mClearCache = builder.shouldClearCache();
//     }
// 
//     public String getCallbackLooperId() {
//         return mCallbackLooperId;
//     }
// 
//     public long getPolicyTimeoutMs() {
//         return mPolicyTimeoutMs;
//     }
// 
//     public long getMaxCacheAgeMs() {
//         return mMaxCacheAgeMs;
//     }
// 
//     public JobPriority getJobPriority() {
//         return mJobPriority;
//     }
// 
//     public boolean isParallelBackgroundCallback() {
//         return mParallelBackgroundCallback;
//     }
// 
//     public boolean shouldBypassCache() {
//         return mBypassCache;
//     }
// 
//     public long getParallelCallbackTimeoutMs() {
//         return mParallelCallbackTimeoutMs;
//     }
// 
//     public boolean shouldClearCache() {
//         return mClearCache;
//     }
// }


import com.bottlerocketstudios.groundcontrol.agent.Agent;
import com.bottlerocketstudios.groundcontrol.listener.AgentListener;
import com.bottlerocketstudios.groundcontrol.policy.AgentPolicy;
/*
 * Copyright (c) 2016. Bottle Rocket LLC
 * 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 com.bottlerocketstudios.groundcontrol.convenience;


/**
 * Create new ExecutionBuilders for each Agent.
 */
public interface ExecutionBuilderFactory {
    /**
     * Create an ExecutionBuilder for use with an agent in UI or background operations.
     */
    <ResultType, ProgressType> ExecutionBuilder<ResultType, ProgressType> createForAgent(Agent<ResultType, ProgressType> agent);

    /**
     * Create an ExecutionBuilder for use with an agent in UI reattach scenarios.
     */
    <ResultType, ProgressType> ExecutionBuilder<ResultType, ProgressType> createForReattach(Object uiObject, String oneTimeIdentifier, String agentIdentifier, AgentListener<ResultType, ProgressType> listener, AgentPolicy agentPolicy);

    /**
     * Register a policy with the ExecutionBuilderFactory to be available to all ExecutionBuilders.
     */
    void registerPolicy(String policyIdentifier, AgentPolicy policy);

    /**
     * Get a policy in the ExecutionBuilderFactory.
     */
// Path: GroundControl/groundcontrol/src/main/java/com/bottlerocketstudios/groundcontrol/agent/Agent.java
// public interface Agent<ResultType, ProgressType> extends Runnable {
//     /**
//      * Provide a globally unique string to identify this agent. All identical agents will
//      * be executed one at a time. If available, cached values for Agents with the same unique
//      * identifier will be delivered.
//      */
//     String getUniqueIdentifier();
// 
//     /**
//      * Stop executing ASAP, your result is no longer needed. If this is a meta-Agent cancel any
//      * associated AgentTethers you have created. This will also be called after cancelTimeoutMs
//      * has elapsed.
//      */
//     void cancel();
// 
//     /**
//      * Maximum amount of time in milliseconds to allow an Agent's run operation to run before being interrupted.
//      * Using a very large number with a repeated task that fails to complete may result in exhausted Thread
//      * pool. Must be greater than getCancelTimeoutMs(). <strong>This value will be read before execution.</strong>
//      */
//     long getRunTimeoutMs();
// 
//     /**
//      * Maximum amount of time in milliseconds starting at run() before cancel() is called if incomplete.
//      * <strong>This value will be read before execution.</strong>
//      */
//     long getCancelTimeoutMs();
// 
//     /**
//      * Maximum amount of time in milliseconds starting at run() to being discarded even if incomplete. Must be
//      * greater than getCancelTimeoutMs() and getRunTimeoutMs(). <strong>This value will be read before execution.</strong>
//      */
//     long getMaximumTimeoutMs();
// 
//     /**
//      * Set the listener for the agent. This listener must be called when the agent has completed or has
//      * progress to deliver.
//      */
//     void setAgentListener(AgentListener<ResultType, ProgressType> agentListener);
// 
//     /**
//      * Set the agentExecutor that will be running this agent. This is guaranteed to be populated before run().
//      * This should be used to spawn further Agent executions and ensures that an Agent could be used with
//      * multiple executors and not be tightly coupled to any specific instance.
//      *
//      * <p><strong>You must not perform work in this operation other than storing the reference.</strong></p>
//      */
//     void setAgentExecutor(AgentExecutor agentExecutor);
// 
//     /**
//      * At the Agent's next convenience, deliver a progress update if applicable. This will be called when
//      * an already running Agent has a new AgentRequest queued.
//      */
//     void onProgressUpdateRequested();
// }
// 
// Path: GroundControl/groundcontrol/src/main/java/com/bottlerocketstudios/groundcontrol/listener/AgentListener.java
// public interface AgentListener<ResultType, ProgressType> {
//     /**
//      * Request has been completed with the associated result value.
//      */
//     void onCompletion(String agentIdentifier, ResultType result);
// 
//     /**
//      * Request is still in progress and provided an update.
//      */
//     void onProgress(String agentIdentifier, ProgressType progress);
// }
// 
// Path: GroundControl/groundcontrol/src/main/java/com/bottlerocketstudios/groundcontrol/policy/AgentPolicy.java
// public class AgentPolicy {
//     private final String mCallbackLooperId;
//     private final long mPolicyTimeoutMs;
//     private final long mParallelCallbackTimeoutMs;
//     private final long mMaxCacheAgeMs;
//     private final JobPriority mJobPriority;
//     private final boolean mParallelBackgroundCallback;
//     private final boolean mBypassCache;
//     private final boolean mClearCache;
// 
//     public AgentPolicy(AgentPolicyBuilder builder) {
//         mCallbackLooperId = builder.getCallbackLooperId();
//         mPolicyTimeoutMs = builder.getPolicyTimeoutMs();
//         mMaxCacheAgeMs = builder.getMaxCacheAgeMs();
//         mJobPriority = builder.getJobPriority();
//         mParallelBackgroundCallback = builder.isParallelBackgroundCallback();
//         mBypassCache = builder.shouldBypassCache();
//         mParallelCallbackTimeoutMs = builder.getParallelCallbackTimeoutMs();
//         mClearCache = builder.shouldClearCache();
//     }
// 
//     public String getCallbackLooperId() {
//         return mCallbackLooperId;
//     }
// 
//     public long getPolicyTimeoutMs() {
//         return mPolicyTimeoutMs;
//     }
// 
//     public long getMaxCacheAgeMs() {
//         return mMaxCacheAgeMs;
//     }
// 
//     public JobPriority getJobPriority() {
//         return mJobPriority;
//     }
// 
//     public boolean isParallelBackgroundCallback() {
//         return mParallelBackgroundCallback;
//     }
// 
//     public boolean shouldBypassCache() {
//         return mBypassCache;
//     }
// 
//     public long getParallelCallbackTimeoutMs() {
//         return mParallelCallbackTimeoutMs;
//     }
// 
//     public boolean shouldClearCache() {
//         return mClearCache;
//     }
// }


// Path: GroundControl/groundcontrol/src/main/java/com/bottlerocketstudios/groundcontrol/convenience/ExecutionBuilderFactory.java
import com.bottlerocketstudios.groundcontrol.agent.Agent;
import com.bottlerocketstudios.groundcontrol.listener.AgentListener;
import com.bottlerocketstudios.groundcontrol.policy.AgentPolicy;

/*
 * Copyright (c) 2016. Bottle Rocket LLC
 * 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 com.bottlerocketstudios.groundcontrol.convenience;


/**
 * Create new ExecutionBuilders for each Agent.
 */
public interface ExecutionBuilderFactory {
    /**
     * Create an ExecutionBuilder for use with an agent in UI or background operations.
     */
    <ResultType, ProgressType> ExecutionBuilder<ResultType, ProgressType> createForAgent(Agent<ResultType, ProgressType> agent);

    /**
     * Create an ExecutionBuilder for use with an agent in UI reattach scenarios.
     */
    <ResultType, ProgressType> ExecutionBuilder<ResultType, ProgressType> createForReattach(Object uiObject, String oneTimeIdentifier, String agentIdentifier, AgentListener<ResultType, ProgressType> listener, AgentPolicy agentPolicy);

    /**
     * Register a policy with the ExecutionBuilderFactory to be available to all ExecutionBuilders.
     */
    void registerPolicy(String policyIdentifier, AgentPolicy policy);

    /**
     * Get a policy in the ExecutionBuilderFactory.
     */
    AgentPolicy getPolicy(String policyIdentifier);