// 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 GoogleCloudOSConfigV1
import GoogleCloudOrgPolicyV1
import GoogleCloudWkt
import GoogleIAMV1
import GoogleIdentityAccessContextManagerV1

/// An asset in Google Cloud. An asset can be any resource in the Google Cloud
/// [resource
/// hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy),
/// a resource outside the Google Cloud resource hierarchy (such as Google
/// Kubernetes Engine clusters and objects), or a policy (e.g. IAM policy),
/// or a relationship (e.g. an INSTANCE_TO_INSTANCEGROUP relationship).
/// See [Supported asset
/// types](https://cloud.google.com/asset-inventory/docs/supported-asset-types)
/// for more information.
public struct Asset: Codable, Equatable, GoogleCloudWkt._AnyPackable,
  Sendable
{
  /// The last update timestamp of an asset. update_time is updated when
  /// create/update/delete operation is performed.
  public var updateTime: GoogleCloudWkt.Timestamp? = nil

  /// The full name of the asset. Example:
  /// `//compute.googleapis.com/projects/my_project_123/zones/zone1/instances/instance1`
  ///
  /// See [Resource
  /// names](https://cloud.google.com/apis/design/resource_names#full_resource_name)
  /// for more information.
  public var name: Swift.String = Swift.String()

  /// The type of the asset. Example: `compute.googleapis.com/Disk`
  ///
  /// See [Supported asset
  /// types](https://cloud.google.com/asset-inventory/docs/supported-asset-types)
  /// for more information.
  public var assetType: Swift.String = Swift.String()

  /// A representation of the resource.
  public var resource: Resource? = nil

  /// A representation of the IAM policy set on a Google Cloud resource.
  /// There can be a maximum of one IAM policy set on any given resource.
  /// In addition, IAM policies inherit their granted access scope from any
  /// policies set on parent resources in the resource hierarchy. Therefore, the
  /// effectively policy is the union of both the policy set on this resource
  /// and each policy set on all of the resource's ancestry resource levels in
  /// the hierarchy. See
  /// [this topic](https://cloud.google.com/iam/help/allow-policies/inheritance)
  /// for more information.
  public var iamPolicy: GoogleIAMV1.Policy? = nil

  /// A representation of an [organization
  /// policy](https://cloud.google.com/resource-manager/docs/organization-policy/overview#organization_policy).
  /// There can be more than one organization policy with different constraints
  /// set on a given resource.
  public var orgPolicy: [GoogleCloudOrgPolicyV1.Policy] = []

  /// A representation of runtime OS Inventory information. See [this
  /// topic](https://cloud.google.com/compute/docs/instances/os-inventory-management)
  /// for more information.
  public var osInventory: GoogleCloudOSConfigV1.Inventory? = nil

  /// DEPRECATED. This field only presents for the purpose of
  /// backward-compatibility. The server will never generate responses with this
  /// field.
  /// The related assets of the asset of one relationship type. One asset
  /// only represents one type of relationship.
  @available(*, deprecated)
  public var relatedAssets: RelatedAssets? = nil

  /// One related asset of the current asset.
  public var relatedAsset: RelatedAsset? = nil

  /// The ancestry path of an asset in Google Cloud [resource
  /// hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy),
  /// represented as a list of relative resource names. An ancestry path starts
  /// with the closest ancestor in the hierarchy and ends at root. If the asset
  /// is a project, folder, or organization, the ancestry path starts from the
  /// asset itself.
  ///
  /// Example: `["projects/123456789", "folders/5432", "organizations/1234"]`
  public var ancestors: [Swift.String] = []

  /// A representation of an [access
  /// policy](https://cloud.google.com/access-context-manager/docs/overview#access-policies).
  public var accessContextPolicy: OneOf_AccessContextPolicy? = nil

  /// Initialize a new instance of `Asset`.
  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 = Asset().with { $0.updateTime = ... }
  /// ```
  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 updateTime = "updateTime"
    case name = "name"
    case assetType = "assetType"
    case resource = "resource"
    case iamPolicy = "iamPolicy"
    case orgPolicy = "orgPolicy"
    case accessPolicy = "accessPolicy"
    case accessLevel = "accessLevel"
    case servicePerimeter = "servicePerimeter"
    case osInventory = "osInventory"
    case relatedAssets = "relatedAssets"
    case relatedAsset = "relatedAsset"
    case ancestors = "ancestors"
  }

  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.updateTime = try container.decodeIfPresent(
      GoogleCloudWkt.Timestamp.self, forKey: .updateTime)
    self.name = try container.decode(Swift.String.self, forKey: .name)
    self.assetType = try container.decode(Swift.String.self, forKey: .assetType)
    self.resource = try container.decodeIfPresent(Resource.self, forKey: .resource)
    self.iamPolicy = try container.decodeIfPresent(GoogleIAMV1.Policy.self, forKey: .iamPolicy)
    self.orgPolicy = try container.decode([GoogleCloudOrgPolicyV1.Policy].self, forKey: .orgPolicy)
    self.osInventory = try container.decodeIfPresent(
      GoogleCloudOSConfigV1.Inventory.self, forKey: .osInventory)
    self.relatedAssets = try container.decodeIfPresent(RelatedAssets.self, forKey: .relatedAssets)
    self.relatedAsset = try container.decodeIfPresent(RelatedAsset.self, forKey: .relatedAsset)
    self.ancestors = try container.decode([Swift.String].self, forKey: .ancestors)

    var accessContextPolicy: OneOf_AccessContextPolicy? = nil
    let accessContextPolicyCheckAndSet = {
      if accessContextPolicy != nil {
        throw DecodingError.dataCorrupted(
          DecodingError.Context(
            codingPath: decoder.codingPath,
            debugDescription: "Multiple values set for oneof 'accessContextPolicy'"))
      }
      accessContextPolicy = $0
    }
    if let accessPolicy = try container.decodeIfPresent(
      GoogleIdentityAccessContextManagerV1.AccessPolicy?.self, forKey: .accessPolicy)
    {
      try accessContextPolicyCheckAndSet(.accessPolicy(accessPolicy))
    }
    if let accessLevel = try container.decodeIfPresent(
      GoogleIdentityAccessContextManagerV1.AccessLevel?.self, forKey: .accessLevel)
    {
      try accessContextPolicyCheckAndSet(.accessLevel(accessLevel))
    }
    if let servicePerimeter = try container.decodeIfPresent(
      GoogleIdentityAccessContextManagerV1.ServicePerimeter?.self, forKey: .servicePerimeter)
    {
      try accessContextPolicyCheckAndSet(.servicePerimeter(servicePerimeter))
    }
    self.accessContextPolicy = accessContextPolicy
  }

  public func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(self.updateTime, forKey: .updateTime)
    try container.encode(self.name, forKey: .name)
    try container.encode(self.assetType, forKey: .assetType)
    try container.encode(self.resource, forKey: .resource)
    try container.encode(self.iamPolicy, forKey: .iamPolicy)
    try container.encode(self.orgPolicy, forKey: .orgPolicy)
    try container.encode(self.osInventory, forKey: .osInventory)
    try container.encode(self.relatedAssets, forKey: .relatedAssets)
    try container.encode(self.relatedAsset, forKey: .relatedAsset)
    try container.encode(self.ancestors, forKey: .ancestors)

    if let choice = self.accessContextPolicy {
      switch choice {
      case .accessPolicy(let value):
        try container.encode(value, forKey: .accessPolicy)
      case .accessLevel(let value):
        try container.encode(value, forKey: .accessLevel)
      case .servicePerimeter(let value):
        try container.encode(value, forKey: .servicePerimeter)
      }
    }
  }

  /// A representation of an [access
  /// policy](https://cloud.google.com/access-context-manager/docs/overview#access-policies).
  public enum OneOf_AccessContextPolicy: Codable, Equatable, Sendable {
    /// Also refer to the [access policy user
    /// guide](https://cloud.google.com/access-context-manager/docs/overview#access-policies).
    indirect case accessPolicy(GoogleIdentityAccessContextManagerV1.AccessPolicy?)
    /// Also refer to the [access level user
    /// guide](https://cloud.google.com/access-context-manager/docs/overview#access-levels).
    indirect case accessLevel(GoogleIdentityAccessContextManagerV1.AccessLevel?)
    /// Also refer to the [service perimeter user
    /// guide](https://cloud.google.com/vpc-service-controls/docs/overview).
    indirect case servicePerimeter(GoogleIdentityAccessContextManagerV1.ServicePerimeter?)
  }

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