// Code generated by sidekick. DO NOT EDIT.
//
// Copyright 2026 Google 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
//
//     https://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.

import Foundation
import GoogleCloudWkt

/// Request message for 'discover' ConnectionProfile request.
public struct DiscoverConnectionProfileRequest: Codable, Equatable, GoogleCloudWkt._AnyPackable,
  Sendable
{
  /// Required. The parent resource of the connection profile type. Must be in
  /// the format `projects/*/locations/*`.
  public var parent: Swift.String = Swift.String()

  /// The connection profile on which to run discover.
  public var target: OneOf_Target? = nil

  /// The depth of the retrieved hierarchy of data objects.
  public var hierarchy: OneOf_Hierarchy? = nil

  /// The data object to populate with child data objects and metadata.
  public var dataObject: OneOf_DataObject? = nil

  /// Initialize a new instance of `DiscoverConnectionProfileRequest`.
  public init() {}

  /// Use `config` to return a new instance of this object, with some fields updated.
  ///
  /// Commonly used to initialize the value, for example:
  ///
  /// ```
  /// let value = DiscoverConnectionProfileRequest().with { $0.parent = ... }
  /// ```
  public func with(_ config: (inout Self) throws -> Swift.Void) rethrows -> Self {
    var copy = self
    try config(&copy)
    return copy
  }

  private enum CodingKeys: Swift.String, CodingKey {
    case parent = "parent"
    case connectionProfile = "connectionProfile"
    case connectionProfileName = "connectionProfileName"
    case fullHierarchy = "fullHierarchy"
    case hierarchyDepth = "hierarchyDepth"
    case oracleRdbms = "oracleRdbms"
    case mysqlRdbms = "mysqlRdbms"
    case postgresqlRdbms = "postgresqlRdbms"
    case sqlServerRdbms = "sqlServerRdbms"
    case salesforceOrg = "salesforceOrg"
    case mongodbCluster = "mongodbCluster"
  }

  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.parent = try container.decode(Swift.String.self, forKey: .parent)

    var target: OneOf_Target? = nil
    let targetCheckAndSet = {
      if target != nil {
        throw DecodingError.dataCorrupted(
          DecodingError.Context(
            codingPath: decoder.codingPath,
            debugDescription: "Multiple values set for oneof 'target'"))
      }
      target = $0
    }
    if let connectionProfile = try container.decodeIfPresent(
      ConnectionProfile?.self, forKey: .connectionProfile)
    {
      try targetCheckAndSet(.connectionProfile(connectionProfile))
    }
    if let connectionProfileName = try container.decodeIfPresent(
      Swift.String.self, forKey: .connectionProfileName)
    {
      try targetCheckAndSet(.connectionProfileName(connectionProfileName))
    }
    self.target = target

    var hierarchy: OneOf_Hierarchy? = nil
    let hierarchyCheckAndSet = {
      if hierarchy != nil {
        throw DecodingError.dataCorrupted(
          DecodingError.Context(
            codingPath: decoder.codingPath,
            debugDescription: "Multiple values set for oneof 'hierarchy'"))
      }
      hierarchy = $0
    }
    if let fullHierarchy = try container.decodeIfPresent(Swift.Bool.self, forKey: .fullHierarchy) {
      try hierarchyCheckAndSet(.fullHierarchy(fullHierarchy))
    }
    if let hierarchyDepth = try container.decodeIfPresent(Swift.Int32.self, forKey: .hierarchyDepth)
    {
      try hierarchyCheckAndSet(.hierarchyDepth(hierarchyDepth))
    }
    self.hierarchy = hierarchy

    var dataObject: OneOf_DataObject? = nil
    let dataObjectCheckAndSet = {
      if dataObject != nil {
        throw DecodingError.dataCorrupted(
          DecodingError.Context(
            codingPath: decoder.codingPath,
            debugDescription: "Multiple values set for oneof 'dataObject'"))
      }
      dataObject = $0
    }
    if let oracleRdbms = try container.decodeIfPresent(OracleRdbms?.self, forKey: .oracleRdbms) {
      try dataObjectCheckAndSet(.oracleRdbms(oracleRdbms))
    }
    if let mysqlRdbms = try container.decodeIfPresent(MysqlRdbms?.self, forKey: .mysqlRdbms) {
      try dataObjectCheckAndSet(.mysqlRdbms(mysqlRdbms))
    }
    if let postgresqlRdbms = try container.decodeIfPresent(
      PostgresqlRdbms?.self, forKey: .postgresqlRdbms)
    {
      try dataObjectCheckAndSet(.postgresqlRdbms(postgresqlRdbms))
    }
    if let sqlServerRdbms = try container.decodeIfPresent(
      SqlServerRdbms?.self, forKey: .sqlServerRdbms)
    {
      try dataObjectCheckAndSet(.sqlServerRdbms(sqlServerRdbms))
    }
    if let salesforceOrg = try container.decodeIfPresent(
      SalesforceOrg?.self, forKey: .salesforceOrg)
    {
      try dataObjectCheckAndSet(.salesforceOrg(salesforceOrg))
    }
    if let mongodbCluster = try container.decodeIfPresent(
      MongodbCluster?.self, forKey: .mongodbCluster)
    {
      try dataObjectCheckAndSet(.mongodbCluster(mongodbCluster))
    }
    self.dataObject = dataObject
  }

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(self.parent, forKey: .parent)

    if let choice = self.target {
      switch choice {
      case .connectionProfile(let value):
        try container.encode(value, forKey: .connectionProfile)
      case .connectionProfileName(let value):
        try container.encode(value, forKey: .connectionProfileName)
      }
    }

    if let choice = self.hierarchy {
      switch choice {
      case .fullHierarchy(let value):
        try container.encode(value, forKey: .fullHierarchy)
      case .hierarchyDepth(let value):
        try container.encode(value, forKey: .hierarchyDepth)
      }
    }

    if let choice = self.dataObject {
      switch choice {
      case .oracleRdbms(let value):
        try container.encode(value, forKey: .oracleRdbms)
      case .mysqlRdbms(let value):
        try container.encode(value, forKey: .mysqlRdbms)
      case .postgresqlRdbms(let value):
        try container.encode(value, forKey: .postgresqlRdbms)
      case .sqlServerRdbms(let value):
        try container.encode(value, forKey: .sqlServerRdbms)
      case .salesforceOrg(let value):
        try container.encode(value, forKey: .salesforceOrg)
      case .mongodbCluster(let value):
        try container.encode(value, forKey: .mongodbCluster)
      }
    }
  }

  /// The connection profile on which to run discover.
  public enum OneOf_Target: Codable, Equatable, Sendable {
    /// An ad-hoc connection profile configuration.
    indirect case connectionProfile(ConnectionProfile?)
    /// A reference to an existing connection profile.
    case connectionProfileName(Swift.String)
  }

  /// The depth of the retrieved hierarchy of data objects.
  public enum OneOf_Hierarchy: Codable, Equatable, Sendable {
    /// Whether to retrieve the full hierarchy of data objects (TRUE) or only the
    /// current level (FALSE).
    case fullHierarchy(Swift.Bool)
    /// The number of hierarchy levels below the current level to be retrieved.
    case hierarchyDepth(Swift.Int32)
  }

  /// The data object to populate with child data objects and metadata.
  public enum OneOf_DataObject: Codable, Equatable, Sendable {
    /// Oracle RDBMS to enrich with child data objects and metadata.
    indirect case oracleRdbms(OracleRdbms?)
    /// MySQL RDBMS to enrich with child data objects and metadata.
    indirect case mysqlRdbms(MysqlRdbms?)
    /// PostgreSQL RDBMS to enrich with child data objects and metadata.
    indirect case postgresqlRdbms(PostgresqlRdbms?)
    /// SQLServer RDBMS to enrich with child data objects and metadata.
    indirect case sqlServerRdbms(SqlServerRdbms?)
    /// Salesforce organization to enrich with child data objects and metadata.
    indirect case salesforceOrg(SalesforceOrg?)
    /// MongoDB cluster to enrich with child data objects and metadata.
    indirect case mongodbCluster(MongodbCluster?)
  }

  public static var _anyTypeUrl: Swift.String {
    return "type.googleapis.com/google.cloud.datastream.v1.DiscoverConnectionProfileRequest"
  }
  public init(fromAny any: GoogleCloudWkt.`Any`) throws {
    self = try GoogleCloudWkt._slowAnyDeserialize(Self.self, from: any)
  }
  public func _pack() throws -> GoogleCloudWkt.Struct {
    return try GoogleCloudWkt._slowAnySerialize(message: self)
  }
}
