// 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

/// Contains an operation for a resource loosely based on the JSON-PATCH format
/// with support for:
///
/// * Custom filters for describing partial array patch.
/// * Extended path values for describing nested arrays.
/// * Custom fields for describing the resource for which the operation is being
///   described.
/// * Allows extension to custom operations not natively supported by RFC6902.
/// See https://tools.ietf.org/html/rfc6902 for details on the original RFC.
public struct Operation: Codable, Equatable, GoogleCloudWkt._AnyPackable,
  Sendable
{
  /// Type of this operation. Contains one of 'add', 'remove', 'replace', 'move',
  /// 'copy', 'test' and custom operations. This field is case-insensitive and
  /// always populated.
  public var action: Swift.String = Swift.String()

  /// Type of GCP resource being modified/tested. This field is always populated.
  /// Example: cloudresourcemanager.googleapis.com/Project,
  /// compute.googleapis.com/Instance
  public var resourceType: Swift.String = Swift.String()

  /// Contains the fully qualified resource name. This field is always populated.
  /// ex: //cloudresourcemanager.googleapis.com/projects/foo.
  public var resource: Swift.String = Swift.String()

  /// Path to the target field being operated on. If the operation is at the
  /// resource level, then path should be "/". This field is always populated.
  public var path: Swift.String = Swift.String()

  /// Can be set with action 'copy' to copy resource configuration across
  /// different resources of the same type. Example: A resource clone can be
  /// done via action = 'copy', path = "/", from = "/",
  /// source_resource = <source> and resource_name = <target>.
  /// This field is empty for all other values of `action`.
  public var sourceResource: Swift.String = Swift.String()

  /// Can be set with action 'copy' or 'move' to indicate the source field within
  /// resource or source_resource, ignored if provided for other operation types.
  public var sourcePath: Swift.String = Swift.String()

  /// Set of filters to apply if `path` refers to array elements or nested array
  /// elements in order to narrow down to a single unique element that is being
  /// tested/modified.
  /// This is intended to be an exact match per filter. To perform advanced
  /// matching, use path_value_matchers.
  ///
  /// * Example:
  /// ```
  /// {
  ///   "/versions/*/name" : "it-123"
  ///   "/versions/*/targetSize/percent": 20
  /// }
  /// ```
  /// * Example:
  /// ```
  /// {
  ///   "/bindings/*/role": "roles/owner"
  ///   "/bindings/*/condition" : null
  /// }
  /// ```
  /// * Example:
  /// ```
  /// {
  ///   "/bindings/*/role": "roles/owner"
  ///   "/bindings/*/members/*" : ["x@example.com", "y@example.com"]
  /// }
  /// ```
  /// When both path_filters and path_value_matchers are set, an implicit AND
  /// must be performed.
  public var pathFilters: [Swift.String: GoogleCloudWkt.Value] = [:]

  /// Similar to path_filters, this contains set of filters to apply if `path`
  /// field refers to array elements. This is meant to support value matching
  /// beyond exact match. To perform exact match, use path_filters.
  /// When both path_filters and path_value_matchers are set, an implicit AND
  /// must be performed.
  public var pathValueMatchers: [Swift.String: ValueMatcher] = [:]

  /// One of the fields in the following block will be set and intend to
  /// describe a value for 'path' field.
  public var pathValue: OneOf_PathValue? = nil

  /// Initialize a new instance of `Operation`.
  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 = Operation().with { $0.action = ... }
  /// ```
  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 action = "action"
    case resourceType = "resourceType"
    case resource = "resource"
    case path = "path"
    case sourceResource = "sourceResource"
    case sourcePath = "sourcePath"
    case value = "value"
    case valueMatcher = "valueMatcher"
    case pathFilters = "pathFilters"
    case pathValueMatchers = "pathValueMatchers"
  }

  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.action = try container.decode(Swift.String.self, forKey: .action)
    self.resourceType = try container.decode(Swift.String.self, forKey: .resourceType)
    self.resource = try container.decode(Swift.String.self, forKey: .resource)
    self.path = try container.decode(Swift.String.self, forKey: .path)
    self.sourceResource = try container.decode(Swift.String.self, forKey: .sourceResource)
    self.sourcePath = try container.decode(Swift.String.self, forKey: .sourcePath)
    self.pathFilters = try container.decode(
      [Swift.String: GoogleCloudWkt.Value].self, forKey: .pathFilters)
    self.pathValueMatchers = try container.decode(
      [Swift.String: ValueMatcher].self, forKey: .pathValueMatchers)

    var pathValue: OneOf_PathValue? = nil
    let pathValueCheckAndSet = {
      if pathValue != nil {
        throw DecodingError.dataCorrupted(
          DecodingError.Context(
            codingPath: decoder.codingPath,
            debugDescription: "Multiple values set for oneof 'pathValue'"))
      }
      pathValue = $0
    }
    if let value = try container.decodeIfPresent(GoogleCloudWkt.Value?.self, forKey: .value) {
      try pathValueCheckAndSet(.value(value))
    }
    if let valueMatcher = try container.decodeIfPresent(ValueMatcher?.self, forKey: .valueMatcher) {
      try pathValueCheckAndSet(.valueMatcher(valueMatcher))
    }
    self.pathValue = pathValue
  }

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(self.action, forKey: .action)
    try container.encode(self.resourceType, forKey: .resourceType)
    try container.encode(self.resource, forKey: .resource)
    try container.encode(self.path, forKey: .path)
    try container.encode(self.sourceResource, forKey: .sourceResource)
    try container.encode(self.sourcePath, forKey: .sourcePath)
    try container.encode(self.pathFilters, forKey: .pathFilters)
    try container.encode(self.pathValueMatchers, forKey: .pathValueMatchers)

    if let choice = self.pathValue {
      switch choice {
      case .value(let value):
        try container.encode(value, forKey: .value)
      case .valueMatcher(let value):
        try container.encode(value, forKey: .valueMatcher)
      }
    }
  }

  /// One of the fields in the following block will be set and intend to
  /// describe a value for 'path' field.
  public enum OneOf_PathValue: Codable, Equatable, Sendable {
    /// Value for the `path` field. Will be set for actions:'add'/'replace'.
    /// Maybe set for action: 'test'. Either this or `value_matcher` will be set
    /// for 'test' operation. An exact match must be performed.
    indirect case value(GoogleCloudWkt.Value?)
    /// Can be set for action 'test' for advanced matching for the value of
    /// 'path' field. Either this or `value` will be set for 'test' operation.
    indirect case valueMatcher(ValueMatcher?)
  }

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