// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.resourcemanager.videoanalyzer.fluent.models;

import com.azure.core.annotation.Fluent;
import com.azure.core.management.ProxyResource;
import com.azure.core.management.SystemData;
import com.azure.core.util.logging.ClientLogger;
import com.azure.resourcemanager.videoanalyzer.models.Kind;
import com.azure.resourcemanager.videoanalyzer.models.ParameterDeclaration;
import com.azure.resourcemanager.videoanalyzer.models.ProcessorNodeBase;
import com.azure.resourcemanager.videoanalyzer.models.SinkNodeBase;
import com.azure.resourcemanager.videoanalyzer.models.Sku;
import com.azure.resourcemanager.videoanalyzer.models.SourceNodeBase;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

/**
 * Pipeline topology describes the processing steps to be applied when processing content for a particular outcome. The
 * topology should be defined according to the scenario to be achieved and can be reused across many pipeline instances
 * which share the same processing characteristics. For instance, a pipeline topology which captures content from a RTSP
 * camera and archives the content can be reused across many different cameras, as long as the same processing is to be
 * applied across all the cameras. Individual instance properties can be defined through the use of user-defined
 * parameters, which allow for a topology to be parameterized. This allows individual pipelines refer to different
 * values, such as individual cameras' RTSP endpoints and credentials. Overall a topology is composed of the following:
 *
 * <p>- Parameters: list of user defined parameters that can be references across the topology nodes. - Sources: list of
 * one or more data sources nodes such as an RTSP source which allows for content to be ingested from cameras. -
 * Processors: list of nodes which perform data analysis or transformations. - Sinks: list of one or more data sinks
 * which allow for data to be stored or exported to other destinations.
 */
@Fluent
public final class PipelineTopologyInner extends ProxyResource {
    /*
     * The resource properties.
     */
    @JsonProperty(value = "properties")
    private PipelineTopologyProperties innerProperties;

    /*
     * Topology kind.
     */
    @JsonProperty(value = "kind", required = true)
    private Kind kind;

    /*
     * Describes the properties of a SKU.
     */
    @JsonProperty(value = "sku", required = true)
    private Sku sku;

    /*
     * Azure Resource Manager metadata containing createdBy and modifiedBy
     * information.
     */
    @JsonProperty(value = "systemData", access = JsonProperty.Access.WRITE_ONLY)
    private SystemData systemData;

    /**
     * Get the innerProperties property: The resource properties.
     *
     * @return the innerProperties value.
     */
    private PipelineTopologyProperties innerProperties() {
        return this.innerProperties;
    }

    /**
     * Get the kind property: Topology kind.
     *
     * @return the kind value.
     */
    public Kind kind() {
        return this.kind;
    }

    /**
     * Set the kind property: Topology kind.
     *
     * @param kind the kind value to set.
     * @return the PipelineTopologyInner object itself.
     */
    public PipelineTopologyInner withKind(Kind kind) {
        this.kind = kind;
        return this;
    }

    /**
     * Get the sku property: Describes the properties of a SKU.
     *
     * @return the sku value.
     */
    public Sku sku() {
        return this.sku;
    }

    /**
     * Set the sku property: Describes the properties of a SKU.
     *
     * @param sku the sku value to set.
     * @return the PipelineTopologyInner object itself.
     */
    public PipelineTopologyInner withSku(Sku sku) {
        this.sku = sku;
        return this;
    }

    /**
     * Get the systemData property: Azure Resource Manager metadata containing createdBy and modifiedBy information.
     *
     * @return the systemData value.
     */
    public SystemData systemData() {
        return this.systemData;
    }

    /**
     * Get the description property: An optional description of the pipeline topology. It is recommended that the
     * expected use of the topology to be described here.
     *
     * @return the description value.
     */
    public String description() {
        return this.innerProperties() == null ? null : this.innerProperties().description();
    }

    /**
     * Set the description property: An optional description of the pipeline topology. It is recommended that the
     * expected use of the topology to be described here.
     *
     * @param description the description value to set.
     * @return the PipelineTopologyInner object itself.
     */
    public PipelineTopologyInner withDescription(String description) {
        if (this.innerProperties() == null) {
            this.innerProperties = new PipelineTopologyProperties();
        }
        this.innerProperties().withDescription(description);
        return this;
    }

    /**
     * Get the parameters property: List of the topology parameter declarations. Parameters declared here can be
     * referenced throughout the topology nodes through the use of "${PARAMETER_NAME}" string pattern. Parameters can
     * have optional default values and can later be defined in individual instances of the pipeline.
     *
     * @return the parameters value.
     */
    public List<ParameterDeclaration> parameters() {
        return this.innerProperties() == null ? null : this.innerProperties().parameters();
    }

    /**
     * Set the parameters property: List of the topology parameter declarations. Parameters declared here can be
     * referenced throughout the topology nodes through the use of "${PARAMETER_NAME}" string pattern. Parameters can
     * have optional default values and can later be defined in individual instances of the pipeline.
     *
     * @param parameters the parameters value to set.
     * @return the PipelineTopologyInner object itself.
     */
    public PipelineTopologyInner withParameters(List<ParameterDeclaration> parameters) {
        if (this.innerProperties() == null) {
            this.innerProperties = new PipelineTopologyProperties();
        }
        this.innerProperties().withParameters(parameters);
        return this;
    }

    /**
     * Get the sources property: List of the topology source nodes. Source nodes enable external data to be ingested by
     * the pipeline.
     *
     * @return the sources value.
     */
    public List<SourceNodeBase> sources() {
        return this.innerProperties() == null ? null : this.innerProperties().sources();
    }

    /**
     * Set the sources property: List of the topology source nodes. Source nodes enable external data to be ingested by
     * the pipeline.
     *
     * @param sources the sources value to set.
     * @return the PipelineTopologyInner object itself.
     */
    public PipelineTopologyInner withSources(List<SourceNodeBase> sources) {
        if (this.innerProperties() == null) {
            this.innerProperties = new PipelineTopologyProperties();
        }
        this.innerProperties().withSources(sources);
        return this;
    }

    /**
     * Get the processors property: List of the topology processor nodes. Processor nodes enable pipeline data to be
     * analyzed, processed or transformed.
     *
     * @return the processors value.
     */
    public List<ProcessorNodeBase> processors() {
        return this.innerProperties() == null ? null : this.innerProperties().processors();
    }

    /**
     * Set the processors property: List of the topology processor nodes. Processor nodes enable pipeline data to be
     * analyzed, processed or transformed.
     *
     * @param processors the processors value to set.
     * @return the PipelineTopologyInner object itself.
     */
    public PipelineTopologyInner withProcessors(List<ProcessorNodeBase> processors) {
        if (this.innerProperties() == null) {
            this.innerProperties = new PipelineTopologyProperties();
        }
        this.innerProperties().withProcessors(processors);
        return this;
    }

    /**
     * Get the sinks property: List of the topology sink nodes. Sink nodes allow pipeline data to be stored or exported.
     *
     * @return the sinks value.
     */
    public List<SinkNodeBase> sinks() {
        return this.innerProperties() == null ? null : this.innerProperties().sinks();
    }

    /**
     * Set the sinks property: List of the topology sink nodes. Sink nodes allow pipeline data to be stored or exported.
     *
     * @param sinks the sinks value to set.
     * @return the PipelineTopologyInner object itself.
     */
    public PipelineTopologyInner withSinks(List<SinkNodeBase> sinks) {
        if (this.innerProperties() == null) {
            this.innerProperties = new PipelineTopologyProperties();
        }
        this.innerProperties().withSinks(sinks);
        return this;
    }

    /**
     * Validates the instance.
     *
     * @throws IllegalArgumentException thrown if the instance is not valid.
     */
    public void validate() {
        if (innerProperties() != null) {
            innerProperties().validate();
        }
        if (kind() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException("Missing required property kind in model PipelineTopologyInner"));
        }
        if (sku() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException("Missing required property sku in model PipelineTopologyInner"));
        } else {
            sku().validate();
        }
    }

    private static final ClientLogger LOGGER = new ClientLogger(PipelineTopologyInner.class);
}
