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

package com.azure.resourcemanager.machinelearning.models;

import com.azure.core.annotation.Fluent;
import com.azure.core.util.logging.ClientLogger;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.util.Map;

/** Sweep job definition. */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "jobType")
@JsonTypeName("Sweep")
@Fluent
public final class SweepJob extends JobBaseProperties {
    /*
     * Early termination policies enable canceling poor-performing runs before they complete
     */
    @JsonProperty(value = "earlyTermination")
    private EarlyTerminationPolicy earlyTermination;

    /*
     * Mapping of input data bindings used in the job.
     */
    @JsonProperty(value = "inputs")
    @JsonInclude(value = JsonInclude.Include.NON_NULL, content = JsonInclude.Include.ALWAYS)
    private Map<String, JobInput> inputs;

    /*
     * Sweep Job limit.
     */
    @JsonProperty(value = "limits")
    private SweepJobLimits limits;

    /*
     * [Required] Optimization objective.
     */
    @JsonProperty(value = "objective", required = true)
    private Objective objective;

    /*
     * Mapping of output data bindings used in the job.
     */
    @JsonProperty(value = "outputs")
    @JsonInclude(value = JsonInclude.Include.NON_NULL, content = JsonInclude.Include.ALWAYS)
    private Map<String, JobOutput> outputs;

    /*
     * [Required] The hyperparameter sampling algorithm
     */
    @JsonProperty(value = "samplingAlgorithm", required = true)
    private SamplingAlgorithm samplingAlgorithm;

    /*
     * [Required] A dictionary containing each parameter and its distribution. The dictionary key is the name of the
     * parameter
     */
    @JsonProperty(value = "searchSpace", required = true)
    private Object searchSpace;

    /*
     * [Required] Trial component definition.
     */
    @JsonProperty(value = "trial", required = true)
    private TrialComponent trial;

    /** Creates an instance of SweepJob class. */
    public SweepJob() {
    }

    /**
     * Get the earlyTermination property: Early termination policies enable canceling poor-performing runs before they
     * complete.
     *
     * @return the earlyTermination value.
     */
    public EarlyTerminationPolicy earlyTermination() {
        return this.earlyTermination;
    }

    /**
     * Set the earlyTermination property: Early termination policies enable canceling poor-performing runs before they
     * complete.
     *
     * @param earlyTermination the earlyTermination value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withEarlyTermination(EarlyTerminationPolicy earlyTermination) {
        this.earlyTermination = earlyTermination;
        return this;
    }

    /**
     * Get the inputs property: Mapping of input data bindings used in the job.
     *
     * @return the inputs value.
     */
    public Map<String, JobInput> inputs() {
        return this.inputs;
    }

    /**
     * Set the inputs property: Mapping of input data bindings used in the job.
     *
     * @param inputs the inputs value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withInputs(Map<String, JobInput> inputs) {
        this.inputs = inputs;
        return this;
    }

    /**
     * Get the limits property: Sweep Job limit.
     *
     * @return the limits value.
     */
    public SweepJobLimits limits() {
        return this.limits;
    }

    /**
     * Set the limits property: Sweep Job limit.
     *
     * @param limits the limits value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withLimits(SweepJobLimits limits) {
        this.limits = limits;
        return this;
    }

    /**
     * Get the objective property: [Required] Optimization objective.
     *
     * @return the objective value.
     */
    public Objective objective() {
        return this.objective;
    }

    /**
     * Set the objective property: [Required] Optimization objective.
     *
     * @param objective the objective value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withObjective(Objective objective) {
        this.objective = objective;
        return this;
    }

    /**
     * Get the outputs property: Mapping of output data bindings used in the job.
     *
     * @return the outputs value.
     */
    public Map<String, JobOutput> outputs() {
        return this.outputs;
    }

    /**
     * Set the outputs property: Mapping of output data bindings used in the job.
     *
     * @param outputs the outputs value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withOutputs(Map<String, JobOutput> outputs) {
        this.outputs = outputs;
        return this;
    }

    /**
     * Get the samplingAlgorithm property: [Required] The hyperparameter sampling algorithm.
     *
     * @return the samplingAlgorithm value.
     */
    public SamplingAlgorithm samplingAlgorithm() {
        return this.samplingAlgorithm;
    }

    /**
     * Set the samplingAlgorithm property: [Required] The hyperparameter sampling algorithm.
     *
     * @param samplingAlgorithm the samplingAlgorithm value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withSamplingAlgorithm(SamplingAlgorithm samplingAlgorithm) {
        this.samplingAlgorithm = samplingAlgorithm;
        return this;
    }

    /**
     * Get the searchSpace property: [Required] A dictionary containing each parameter and its distribution. The
     * dictionary key is the name of the parameter.
     *
     * @return the searchSpace value.
     */
    public Object searchSpace() {
        return this.searchSpace;
    }

    /**
     * Set the searchSpace property: [Required] A dictionary containing each parameter and its distribution. The
     * dictionary key is the name of the parameter.
     *
     * @param searchSpace the searchSpace value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withSearchSpace(Object searchSpace) {
        this.searchSpace = searchSpace;
        return this;
    }

    /**
     * Get the trial property: [Required] Trial component definition.
     *
     * @return the trial value.
     */
    public TrialComponent trial() {
        return this.trial;
    }

    /**
     * Set the trial property: [Required] Trial component definition.
     *
     * @param trial the trial value to set.
     * @return the SweepJob object itself.
     */
    public SweepJob withTrial(TrialComponent trial) {
        this.trial = trial;
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withComponentId(String componentId) {
        super.withComponentId(componentId);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withComputeId(String computeId) {
        super.withComputeId(computeId);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withDisplayName(String displayName) {
        super.withDisplayName(displayName);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withExperimentName(String experimentName) {
        super.withExperimentName(experimentName);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withIdentity(IdentityConfiguration identity) {
        super.withIdentity(identity);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withIsArchived(Boolean isArchived) {
        super.withIsArchived(isArchived);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withServices(Map<String, JobService> services) {
        super.withServices(services);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withDescription(String description) {
        super.withDescription(description);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withProperties(Map<String, String> properties) {
        super.withProperties(properties);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public SweepJob withTags(Map<String, String> tags) {
        super.withTags(tags);
        return this;
    }

    /**
     * Validates the instance.
     *
     * @throws IllegalArgumentException thrown if the instance is not valid.
     */
    @Override
    public void validate() {
        super.validate();
        if (earlyTermination() != null) {
            earlyTermination().validate();
        }
        if (inputs() != null) {
            inputs()
                .values()
                .forEach(
                    e -> {
                        if (e != null) {
                            e.validate();
                        }
                    });
        }
        if (limits() != null) {
            limits().validate();
        }
        if (objective() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException("Missing required property objective in model SweepJob"));
        } else {
            objective().validate();
        }
        if (outputs() != null) {
            outputs()
                .values()
                .forEach(
                    e -> {
                        if (e != null) {
                            e.validate();
                        }
                    });
        }
        if (samplingAlgorithm() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException("Missing required property samplingAlgorithm in model SweepJob"));
        } else {
            samplingAlgorithm().validate();
        }
        if (searchSpace() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException("Missing required property searchSpace in model SweepJob"));
        }
        if (trial() == null) {
            throw LOGGER
                .logExceptionAsError(new IllegalArgumentException("Missing required property trial in model SweepJob"));
        } else {
            trial().validate();
        }
    }

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