/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.camel.builder.endpoint.dsl;

import javax.annotation.Generated;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;

/**
 * The DigitalOcean component allows you to manage Droplets and resources within
 * the DigitalOcean cloud.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface DigitalOceanEndpointBuilderFactory {


    /**
     * Builder for endpoint for the DigitalOcean component.
     */
    public interface DigitalOceanEndpointBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedDigitalOceanEndpointBuilder advanced() {
            return (AdvancedDigitalOceanEndpointBuilder) this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default DigitalOceanEndpointBuilder lazyStartProducer(
                boolean lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default DigitalOceanEndpointBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Use for pagination. Force the page number.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: producer
         */
        default DigitalOceanEndpointBuilder page(Integer page) {
            doSetProperty("page", page);
            return this;
        }
        /**
         * Use for pagination. Force the page number.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: producer
         */
        default DigitalOceanEndpointBuilder page(String page) {
            doSetProperty("page", page);
            return this;
        }
        /**
         * Use for pagination. Set the number of item per request. The maximum
         * number of results per page is 200.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: producer
         */
        default DigitalOceanEndpointBuilder perPage(Integer perPage) {
            doSetProperty("perPage", perPage);
            return this;
        }
        /**
         * Use for pagination. Set the number of item per request. The maximum
         * number of results per page is 200.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: producer
         */
        default DigitalOceanEndpointBuilder perPage(String perPage) {
            doSetProperty("perPage", perPage);
            return this;
        }
        /**
         * The DigitalOcean resource type on which perform the operation.
         * 
         * The option is a:
         * <code>org.apache.camel.component.digitalocean.constants.DigitalOceanResources</code> type.
         * 
         * Required: true
         * Group: producer
         */
        default DigitalOceanEndpointBuilder resource(
                DigitalOceanResources resource) {
            doSetProperty("resource", resource);
            return this;
        }
        /**
         * The DigitalOcean resource type on which perform the operation.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.digitalocean.constants.DigitalOceanResources</code> type.
         * 
         * Required: true
         * Group: producer
         */
        default DigitalOceanEndpointBuilder resource(String resource) {
            doSetProperty("resource", resource);
            return this;
        }
        /**
         * Set a proxy host if needed.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: proxy
         */
        default DigitalOceanEndpointBuilder httpProxyHost(String httpProxyHost) {
            doSetProperty("httpProxyHost", httpProxyHost);
            return this;
        }
        /**
         * Set a proxy password if needed.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: proxy
         */
        default DigitalOceanEndpointBuilder httpProxyPassword(
                String httpProxyPassword) {
            doSetProperty("httpProxyPassword", httpProxyPassword);
            return this;
        }
        /**
         * Set a proxy port if needed.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: proxy
         */
        default DigitalOceanEndpointBuilder httpProxyPort(Integer httpProxyPort) {
            doSetProperty("httpProxyPort", httpProxyPort);
            return this;
        }
        /**
         * Set a proxy port if needed.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: proxy
         */
        default DigitalOceanEndpointBuilder httpProxyPort(String httpProxyPort) {
            doSetProperty("httpProxyPort", httpProxyPort);
            return this;
        }
        /**
         * Set a proxy host if needed.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: proxy
         */
        default DigitalOceanEndpointBuilder httpProxyUser(String httpProxyUser) {
            doSetProperty("httpProxyUser", httpProxyUser);
            return this;
        }
        /**
         * DigitalOcean OAuth Token.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default DigitalOceanEndpointBuilder oAuthToken(String oAuthToken) {
            doSetProperty("oAuthToken", oAuthToken);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the DigitalOcean component.
     */
    public interface AdvancedDigitalOceanEndpointBuilder
            extends
                EndpointProducerBuilder {
        default DigitalOceanEndpointBuilder basic() {
            return (DigitalOceanEndpointBuilder) this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedDigitalOceanEndpointBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedDigitalOceanEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * To use a existing configured DigitalOceanClient as client.
         * 
         * The option is a:
         * <code>com.myjeeva.digitalocean.impl.DigitalOceanClient</code> type.
         * 
         * Group: advanced
         */
        default AdvancedDigitalOceanEndpointBuilder digitalOceanClient(
                Object digitalOceanClient) {
            doSetProperty("digitalOceanClient", digitalOceanClient);
            return this;
        }
        /**
         * To use a existing configured DigitalOceanClient as client.
         * 
         * The option will be converted to a
         * <code>com.myjeeva.digitalocean.impl.DigitalOceanClient</code> type.
         * 
         * Group: advanced
         */
        default AdvancedDigitalOceanEndpointBuilder digitalOceanClient(
                String digitalOceanClient) {
            doSetProperty("digitalOceanClient", digitalOceanClient);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedDigitalOceanEndpointBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedDigitalOceanEndpointBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.digitalocean.constants.DigitalOceanResources</code> enum.
     */
    enum DigitalOceanResources {
        account,
        actions,
        blockStorages,
        droplets,
        images,
        snapshots,
        keys,
        regions,
        sizes,
        floatingIPs,
        tags;
    }
    /**
     * DigitalOcean (camel-digitalocean)
     * The DigitalOcean component allows you to manage Droplets and resources
     * within the DigitalOcean cloud.
     * 
     * Category: cloud,management
     * Since: 2.19
     * Maven coordinates: org.apache.camel:camel-digitalocean
     * 
     * Syntax: <code>digitalocean:operation</code>
     * 
     * Path parameter: operation
     * The operation to perform to the given resource.
     * The value can be one of: create, update, delete, list, ownList, get,
     * listBackups, listActions, listNeighbors, listSnapshots, listKernels,
     * listAllNeighbors, enableBackups, disableBackups, reboot, powerCycle,
     * shutdown, powerOn, powerOff, restore, resetPassword, resize, rebuild,
     * rename, changeKernel, enableIpv6, enablePrivateNetworking, takeSnapshot,
     * transfer, convert, attach, detach, assign, unassign, tag, untag
     */
    default DigitalOceanEndpointBuilder digitalocean(String path) {
        class DigitalOceanEndpointBuilderImpl extends AbstractEndpointBuilder implements DigitalOceanEndpointBuilder, AdvancedDigitalOceanEndpointBuilder {
            public DigitalOceanEndpointBuilderImpl(String path) {
                super("digitalocean", path);
            }
        }
        return new DigitalOceanEndpointBuilderImpl(path);
    }
}