// 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.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.util.List;

/**
 * Image Classification. Multi-class image classification is used when an image is classified with only a single label
 * from a set of classes - e.g. each image is classified as either an image of a 'cat' or a 'dog' or a 'duck'.
 */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "taskType")
@JsonTypeName("ImageClassification")
@Fluent
public final class ImageClassification extends AutoMLVertical {
    /*
     * Primary metric to optimize for this task.
     */
    @JsonProperty(value = "primaryMetric")
    private ClassificationPrimaryMetrics primaryMetric;

    /*
     * Settings used for training the model.
     */
    @JsonProperty(value = "modelSettings")
    private ImageModelSettingsClassification modelSettings;

    /*
     * Search space for sampling different combinations of models and their hyperparameters.
     */
    @JsonProperty(value = "searchSpace")
    private List<ImageModelDistributionSettingsClassification> searchSpace;

    /*
     * [Required] Limit settings for the AutoML job.
     */
    @JsonProperty(value = "limitSettings", required = true)
    private ImageLimitSettings limitSettings;

    /*
     * Model sweeping and hyperparameter sweeping related settings.
     */
    @JsonProperty(value = "sweepSettings")
    private ImageSweepSettings sweepSettings;

    /*
     * Validation data inputs.
     */
    @JsonProperty(value = "validationData")
    private MLTableJobInput validationData;

    /*
     * The fraction of training dataset that needs to be set aside for validation purpose.
     * Values between (0.0 , 1.0)
     * Applied when validation dataset is not provided.
     */
    @JsonProperty(value = "validationDataSize")
    private Double validationDataSize;

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

    /**
     * Get the primaryMetric property: Primary metric to optimize for this task.
     *
     * @return the primaryMetric value.
     */
    public ClassificationPrimaryMetrics primaryMetric() {
        return this.primaryMetric;
    }

    /**
     * Set the primaryMetric property: Primary metric to optimize for this task.
     *
     * @param primaryMetric the primaryMetric value to set.
     * @return the ImageClassification object itself.
     */
    public ImageClassification withPrimaryMetric(ClassificationPrimaryMetrics primaryMetric) {
        this.primaryMetric = primaryMetric;
        return this;
    }

    /**
     * Get the modelSettings property: Settings used for training the model.
     *
     * @return the modelSettings value.
     */
    public ImageModelSettingsClassification modelSettings() {
        return this.modelSettings;
    }

    /**
     * Set the modelSettings property: Settings used for training the model.
     *
     * @param modelSettings the modelSettings value to set.
     * @return the ImageClassification object itself.
     */
    public ImageClassification withModelSettings(ImageModelSettingsClassification modelSettings) {
        this.modelSettings = modelSettings;
        return this;
    }

    /**
     * Get the searchSpace property: Search space for sampling different combinations of models and their
     * hyperparameters.
     *
     * @return the searchSpace value.
     */
    public List<ImageModelDistributionSettingsClassification> searchSpace() {
        return this.searchSpace;
    }

    /**
     * Set the searchSpace property: Search space for sampling different combinations of models and their
     * hyperparameters.
     *
     * @param searchSpace the searchSpace value to set.
     * @return the ImageClassification object itself.
     */
    public ImageClassification withSearchSpace(List<ImageModelDistributionSettingsClassification> searchSpace) {
        this.searchSpace = searchSpace;
        return this;
    }

    /**
     * Get the limitSettings property: [Required] Limit settings for the AutoML job.
     *
     * @return the limitSettings value.
     */
    public ImageLimitSettings limitSettings() {
        return this.limitSettings;
    }

    /**
     * Set the limitSettings property: [Required] Limit settings for the AutoML job.
     *
     * @param limitSettings the limitSettings value to set.
     * @return the ImageClassification object itself.
     */
    public ImageClassification withLimitSettings(ImageLimitSettings limitSettings) {
        this.limitSettings = limitSettings;
        return this;
    }

    /**
     * Get the sweepSettings property: Model sweeping and hyperparameter sweeping related settings.
     *
     * @return the sweepSettings value.
     */
    public ImageSweepSettings sweepSettings() {
        return this.sweepSettings;
    }

    /**
     * Set the sweepSettings property: Model sweeping and hyperparameter sweeping related settings.
     *
     * @param sweepSettings the sweepSettings value to set.
     * @return the ImageClassification object itself.
     */
    public ImageClassification withSweepSettings(ImageSweepSettings sweepSettings) {
        this.sweepSettings = sweepSettings;
        return this;
    }

    /**
     * Get the validationData property: Validation data inputs.
     *
     * @return the validationData value.
     */
    public MLTableJobInput validationData() {
        return this.validationData;
    }

    /**
     * Set the validationData property: Validation data inputs.
     *
     * @param validationData the validationData value to set.
     * @return the ImageClassification object itself.
     */
    public ImageClassification withValidationData(MLTableJobInput validationData) {
        this.validationData = validationData;
        return this;
    }

    /**
     * Get the validationDataSize property: The fraction of training dataset that needs to be set aside for validation
     * purpose. Values between (0.0 , 1.0) Applied when validation dataset is not provided.
     *
     * @return the validationDataSize value.
     */
    public Double validationDataSize() {
        return this.validationDataSize;
    }

    /**
     * Set the validationDataSize property: The fraction of training dataset that needs to be set aside for validation
     * purpose. Values between (0.0 , 1.0) Applied when validation dataset is not provided.
     *
     * @param validationDataSize the validationDataSize value to set.
     * @return the ImageClassification object itself.
     */
    public ImageClassification withValidationDataSize(Double validationDataSize) {
        this.validationDataSize = validationDataSize;
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public ImageClassification withLogVerbosity(LogVerbosity logVerbosity) {
        super.withLogVerbosity(logVerbosity);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public ImageClassification withTargetColumnName(String targetColumnName) {
        super.withTargetColumnName(targetColumnName);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public ImageClassification withTrainingData(MLTableJobInput trainingData) {
        super.withTrainingData(trainingData);
        return this;
    }

    /**
     * Validates the instance.
     *
     * @throws IllegalArgumentException thrown if the instance is not valid.
     */
    @Override
    public void validate() {
        super.validate();
        if (modelSettings() != null) {
            modelSettings().validate();
        }
        if (searchSpace() != null) {
            searchSpace().forEach(e -> e.validate());
        }
        if (limitSettings() == null) {
            throw LOGGER
                .logExceptionAsError(
                    new IllegalArgumentException(
                        "Missing required property limitSettings in model ImageClassification"));
        } else {
            limitSettings().validate();
        }
        if (sweepSettings() != null) {
            sweepSettings().validate();
        }
        if (validationData() != null) {
            validationData().validate();
        }
    }

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