// 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
/// [ConversationalSearchService.ConversationalSearch][google.cloud.retail.v2.ConversationalSearchService.ConversationalSearch]
/// method.
///
/// [google.cloud.retail.v2.ConversationalSearchService.ConversationalSearch]: <doc:ConversationalSearchService/conversationalSearch(request:)>
public struct ConversationalSearchRequest: Codable, Equatable, GoogleCloudWkt._AnyPackable,
  Sendable
{
  /// Required. The resource name of the search engine placement, such as
  /// `projects/*/locations/global/catalogs/default_catalog/placements/default_search`
  /// or
  /// `projects/*/locations/global/catalogs/default_catalog/servingConfigs/default_serving_config`
  /// This field is used to identify the serving config name and the set
  /// of models that will be used to make the search.
  public var placement: Swift.String = Swift.String()

  /// Required. The branch resource name, such as
  /// `projects/*/locations/global/catalogs/default_catalog/branches/0`.
  ///
  /// Use "default_branch" as the branch ID or leave this field empty, to search
  /// products under the default branch.
  public var branch: Swift.String = Swift.String()

  /// Optional. Raw search query to be searched for.
  ///
  /// If this field is empty, the request is considered a category browsing
  /// request.
  public var query: Swift.String = Swift.String()

  /// Optional. The categories associated with a category page. Must be set for
  /// category navigation queries to achieve good search quality. The format
  /// should be the same as
  /// [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories];
  ///
  /// To represent full path of category, use '>' sign to separate different
  /// hierarchies. If '>' is part of the category name, replace it with
  /// other character(s).
  ///
  /// Category pages include special pages such as sales or promotions. For
  /// instance, a special sale page may have the category hierarchy:
  /// "pageCategories" : ["Sales > 2017 Black Friday Deals"].
  ///
  /// [google.cloud.retail.v2.UserEvent.page_categories]: <doc:UserEvent/pageCategories>
  public var pageCategories: [Swift.String] = []

  /// Optional. This field specifies the conversation id, which maintains the
  /// state of the conversation between client side and server side. Use the
  /// value from the previous
  /// [ConversationalSearchResponse.conversation_id][google.cloud.retail.v2.ConversationalSearchResponse.conversation_id].
  /// For the initial request, this should be empty.
  ///
  /// [google.cloud.retail.v2.ConversationalSearchResponse.conversation_id]: <doc:ConversationalSearchResponse/conversationId>
  public var conversationId: Swift.String = Swift.String()

  /// Optional. Search parameters.
  public var searchParams: ConversationalSearchRequest.SearchParams? = nil

  /// Required. A unique identifier for tracking visitors. For example, this
  /// could be implemented with an HTTP cookie, which should be able to uniquely
  /// identify a visitor on a single device. This unique identifier should not
  /// change if the visitor logs in or out of the website.
  ///
  /// This should be the same identifier as
  /// [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id].
  ///
  /// The field must be a UTF-8 encoded string with a length limit of 128
  /// characters. Otherwise, an INVALID_ARGUMENT error is returned.
  ///
  /// [google.cloud.retail.v2.UserEvent.visitor_id]: <doc:UserEvent/visitorId>
  public var visitorId: Swift.String = Swift.String()

  /// Optional. User information.
  public var userInfo: UserInfo? = nil

  /// Optional. This field specifies all conversational filtering related
  /// parameters.
  public var conversationalFilteringSpec: ConversationalSearchRequest.ConversationalFilteringSpec? =
    nil

  /// Optional. The user labels applied to a resource must meet the following
  /// requirements:
  ///
  /// * Each resource can have multiple labels, up to a maximum of 64.
  /// * Each label must be a key-value pair.
  /// * Keys have a minimum length of 1 character and a maximum length of 63
  ///   characters and cannot be empty. Values can be empty and have a maximum
  ///   length of 63 characters.
  /// * Keys and values can contain only lowercase letters, numeric characters,
  ///   underscores, and dashes. All characters must use UTF-8 encoding, and
  ///   international characters are allowed.
  /// * The key portion of a label must be unique. However, you can use the same
  ///   key with multiple resources.
  /// * Keys must start with a lowercase letter or international character.
  ///
  /// See [Google Cloud
  /// Document](https://cloud.google.com/resource-manager/docs/creating-managing-labels#requirements)
  /// for more details.
  public var userLabels: [Swift.String: Swift.String] = [:]

  /// Optional. The safety settings to be applied to the generated content.
  public var safetySettings: [SafetySetting] = []

  /// Initialize a new instance of `ConversationalSearchRequest`.
  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 = ConversationalSearchRequest().with { $0.placement = ... }
  /// ```
  public func with(_ config: (inout Self) throws -> Swift.Void) rethrows -> Self {
    var copy = self
    try config(&copy)
    return copy
  }

  /// Search parameters.
  public struct SearchParams: Codable, Equatable, GoogleCloudWkt._AnyPackable,
    Sendable
  {
    /// Optional. The filter string to restrict search results.
    ///
    /// The syntax of the filter string is the same as
    /// [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter].
    ///
    /// [google.cloud.retail.v2.SearchRequest.filter]: <doc:SearchRequest/filter>
    public var filter: Swift.String = Swift.String()

    /// Optional. The canonical filter string to restrict search results.
    ///
    /// The syntax of the canonical filter string is the same as
    /// [SearchRequest.canonical_filter][google.cloud.retail.v2.SearchRequest.canonical_filter].
    ///
    /// [google.cloud.retail.v2.SearchRequest.canonical_filter]: <doc:SearchRequest/canonicalFilter>
    public var canonicalFilter: Swift.String = Swift.String()

    /// Optional. The sort string to specify the sorting of search results.
    ///
    /// The syntax of the sort string is the same as
    /// [SearchRequest.sort][].
    public var sortBy: Swift.String = Swift.String()

    /// Optional. The boost spec to specify the boosting of search results.
    ///
    /// The syntax of the boost spec is the same as
    /// [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec].
    ///
    /// [google.cloud.retail.v2.SearchRequest.boost_spec]: <doc:SearchRequest/boostSpec>
    public var boostSpec: SearchRequest.BoostSpec? = nil

    /// Initialize a new instance of `SearchParams`.
    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 = SearchParams().with { $0.filter = ... }
    /// ```
    public func with(_ config: (inout Self) throws -> Swift.Void) rethrows -> Self {
      var copy = self
      try config(&copy)
      return copy
    }

    public static var _anyTypeUrl: Swift.String {
      return "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.SearchParams"
    }
    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)
    }
  }

  /// This field specifies the current user answer during the conversational
  /// filtering search. This can be either user selected from suggested answers
  /// or user input plain text.
  public struct UserAnswer: Codable, Equatable, GoogleCloudWkt._AnyPackable,
    Sendable
  {
    /// This field specifies the type of user answer.
    public var type: OneOf_Type_? = nil

    /// Initialize a new instance of `UserAnswer`.
    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 = UserAnswer().with { $0.textAnswer = ... }
    /// ```
    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 textAnswer = "textAnswer"
      case selectedAnswer = "selectedAnswer"
    }

    public init(from decoder: Decoder) throws {
      let container = try decoder.container(keyedBy: CodingKeys.self)

      var type: OneOf_Type_? = nil
      let typeCheckAndSet = {
        if type != nil {
          throw DecodingError.dataCorrupted(
            DecodingError.Context(
              codingPath: decoder.codingPath,
              debugDescription: "Multiple values set for oneof 'type'"))
        }
        type = $0
      }
      if let textAnswer = try container.decodeIfPresent(Swift.String.self, forKey: .textAnswer) {
        try typeCheckAndSet(.textAnswer(textAnswer))
      }
      if let selectedAnswer = try container.decodeIfPresent(
        ConversationalSearchRequest.UserAnswer.SelectedAnswer?.self, forKey: .selectedAnswer)
      {
        try typeCheckAndSet(.selectedAnswer(selectedAnswer))
      }
      self.type = type
    }

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

      if let choice = self.type {
        switch choice {
        case .textAnswer(let value):
          try container.encode(value, forKey: .textAnswer)
        case .selectedAnswer(let value):
          try container.encode(value, forKey: .selectedAnswer)
        }
      }
    }

    /// This field specifies the selected answers during the conversational
    /// search.
    public struct SelectedAnswer: Codable, Equatable, GoogleCloudWkt._AnyPackable,
      Sendable
    {
      /// Optional. This field specifies the selected answer which is a attribute
      /// key-value.
      public var productAttributeValue: ProductAttributeValue? = nil

      /// Initialize a new instance of `SelectedAnswer`.
      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 = SelectedAnswer().with { $0.productAttributeValue = ... }
      /// ```
      public func with(_ config: (inout Self) throws -> Swift.Void) rethrows -> Self {
        var copy = self
        try config(&copy)
        return copy
      }

      public static var _anyTypeUrl: Swift.String {
        return
          "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.UserAnswer.SelectedAnswer"
      }
      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)
      }
    }

    /// This field specifies the type of user answer.
    public enum OneOf_Type_: Codable, Equatable, Sendable {
      /// This field specifies the incremental input text from the user during
      /// the conversational search.
      case textAnswer(Swift.String)
      /// Optional. This field specifies the selected answer during the
      /// conversational search. This should be a subset of
      /// [ConversationalSearchResponse.followup_question.suggested_answers][].
      indirect case selectedAnswer(ConversationalSearchRequest.UserAnswer.SelectedAnswer?)
    }

    public static var _anyTypeUrl: Swift.String {
      return "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.UserAnswer"
    }
    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)
    }
  }

  /// This field specifies all conversational filtering related parameters
  /// addition to conversational retail search.
  public struct ConversationalFilteringSpec: Codable, Equatable, GoogleCloudWkt._AnyPackable,
    Sendable
  {
    /// Optional. This field is deprecated. Please use
    /// [ConversationalFilteringSpec.conversational_filtering_mode][google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.conversational_filtering_mode]
    /// instead.
    ///
    /// [google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.conversational_filtering_mode]: <doc:ConversationalSearchRequest/ConversationalFilteringSpec/conversationalFilteringMode>
    @available(*, deprecated)
    public var enableConversationalFiltering: Swift.Bool = Swift.Bool()

    /// Optional. This field specifies the current user answer during the
    /// conversational filtering search. It can be either user selected from
    /// suggested answers or user input plain text.
    public var userAnswer: ConversationalSearchRequest.UserAnswer? = nil

    /// Optional. Mode to control Conversational Filtering.
    /// Defaults to
    /// [Mode.DISABLED][google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.Mode.DISABLED]
    /// if it's unset.
    ///
    /// [google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec.Mode.DISABLED]: <doc:ConversationalSearchRequest/ConversationalFilteringSpec/Mode/disabled>
    public var conversationalFilteringMode:
      ConversationalSearchRequest.ConversationalFilteringSpec.Mode = ConversationalSearchRequest
        .ConversationalFilteringSpec.Mode()

    /// Initialize a new instance of `ConversationalFilteringSpec`.
    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 = ConversationalFilteringSpec().with { $0.enableConversationalFiltering = ... }
    /// ```
    public func with(_ config: (inout Self) throws -> Swift.Void) rethrows -> Self {
      var copy = self
      try config(&copy)
      return copy
    }

    /// Enum to control Conversational Filtering mode.
    /// A single conversation session including multiple turns supports modes for
    /// Conversational Search OR Conversational Filtering without
    /// Conversational Search, but not both.
    public enum Mode: Codable, Equatable, Sendable {
      /// Default value.
      case unspecified
      /// Disables Conversational Filtering when using Conversational Search.
      case disabled
      /// Enables Conversational Filtering when using Conversational Search.
      case enabled
      /// Enables Conversational Filtering without Conversational Search.
      case conversationalFilterOnly
      /// Encodes an unknown integer value.
      ///
      /// The most common cause for an unknown values is for the service to send
      /// a value unknown to the library. We recommend you update your library to
      /// the latest version.
      case unknownIntValue(Int)
      /// Encodes an unknown string value.
      ///
      /// The most common cause for an unknown values is for the service to send
      /// a value unknown to the library. We recommend you update your library to
      /// the latest version.
      case unknownStringValue(String)

      public init() {
        self = .unspecified
      }

      /// Returns the integer value associated with the enumeration.
      ///
      /// If the enumeration was initialized with an unknown string value, this returns `nil`.
      public var intValue: Int? {
        switch self {
        case .unspecified: return 0
        case .disabled: return 1
        case .enabled: return 2
        case .conversationalFilterOnly: return 3
        case .unknownIntValue(let v): return v
        case .unknownStringValue: return nil
        }
      }

      /// Returns the string value (or name) associated with the enumeration.
      ///
      /// If the enumeration was initialized with an unknown integer value, this returns `nil`.
      public var stringValue: Swift.String? {
        switch self {
        case .unspecified: return "MODE_UNSPECIFIED"
        case .disabled: return "DISABLED"
        case .enabled: return "ENABLED"
        case .conversationalFilterOnly: return "CONVERSATIONAL_FILTER_ONLY"
        case .unknownIntValue: return nil
        case .unknownStringValue(let v): return v
        }
      }

      /// Initialize from a string value.
      ///
      /// If the value is unknown, this initializes to [`unknownStringValue`](doc:Mode/unknownStringValue(_:)).
      public init(stringValue: Swift.String) {
        switch stringValue {
        case "MODE_UNSPECIFIED": self = .unspecified
        case "DISABLED": self = .disabled
        case "ENABLED": self = .enabled
        case "CONVERSATIONAL_FILTER_ONLY": self = .conversationalFilterOnly
        default: self = .unknownStringValue(stringValue)
        }
      }

      /// Initialize from an integer value.
      ///
      /// If the value is unknown, this initializes to [`unknownIntValue`](doc:Mode/unknownIntValue(_:)).
      public init(intValue: Int) {
        switch intValue {
        case 0: self = .unspecified
        case 1: self = .disabled
        case 2: self = .enabled
        case 3: self = .conversationalFilterOnly
        default: self = .unknownIntValue(intValue)
        }
      }

      public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let v = try? container.decode(Int.self) {
          self.init(intValue: v)
          return
        }
        if let s = try? container.decode(String.self) {
          if let v = Int(s) {
            self.init(intValue: v)
          } else {
            self.init(stringValue: s)
          }
          return
        }
        throw DecodingError.dataCorruptedError(
          in: container, debugDescription: "Expected enum value, must be integer or string.")
      }

      public func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .unspecified: return try container.encode(0)
        case .disabled: return try container.encode(1)
        case .enabled: return try container.encode(2)
        case .conversationalFilterOnly: return try container.encode(3)
        case .unknownIntValue(let v): return try container.encode(v)
        case .unknownStringValue(let v): return try container.encode(v)
        }
      }
    }

    public static var _anyTypeUrl: Swift.String {
      return
        "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest.ConversationalFilteringSpec"
    }
    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)
    }
  }

  public static var _anyTypeUrl: Swift.String {
    return "type.googleapis.com/google.cloud.retail.v2.ConversationalSearchRequest"
  }
  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)
  }
}
