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

/// Logged event discussing an abuse finding on the monitored resource.
public struct AbuseEvent: Codable, Equatable, GoogleCloudWkt._AnyPackable,
  Sendable
{
  /// REQUIRED Correlates to the abuse finding causing the notification.
  public var detectionType: AbuseEvent.DetectionType = AbuseEvent.DetectionType()

  /// REQUIRED Explains the meaning of the detection_type.
  public var reason: Swift.String = Swift.String()

  /// REQUIRED Correlates to the action taken on the monitored resource.
  public var action: AbuseEvent.ActionType = AbuseEvent.ActionType()

  /// Contains the umbrella link for remediation after an abuse notification.
  public var remediationLink: Swift.String = Swift.String()

  /// REQUIRED Contains addiional metadata about the detected abuse event.
  public var eventType: OneOf_EventType? = nil

  /// Initialize a new instance of `AbuseEvent`.
  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 = AbuseEvent().with { $0.detectionType = ... }
  /// ```
  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 detectionType = "detectionType"
    case reason = "reason"
    case action = "action"
    case cryptoMiningEvent = "cryptoMiningEvent"
    case leakedCredentialEvent = "leakedCredentialEvent"
    case harmfulContentEvent = "harmfulContentEvent"
    case reinstatementEvent = "reinstatementEvent"
    case decisionEscalationEvent = "decisionEscalationEvent"
    case intrusionAttemptEvent = "intrusionAttemptEvent"
    case remediationLink = "remediationLink"
  }

  public init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.detectionType = try container.decode(AbuseEvent.DetectionType.self, forKey: .detectionType)
    self.reason = try container.decode(Swift.String.self, forKey: .reason)
    self.action = try container.decode(AbuseEvent.ActionType.self, forKey: .action)
    self.remediationLink = try container.decode(Swift.String.self, forKey: .remediationLink)

    var eventType: OneOf_EventType? = nil
    let eventTypeCheckAndSet = {
      if eventType != nil {
        throw DecodingError.dataCorrupted(
          DecodingError.Context(
            codingPath: decoder.codingPath,
            debugDescription: "Multiple values set for oneof 'eventType'"))
      }
      eventType = $0
    }
    if let cryptoMiningEvent = try container.decodeIfPresent(
      CryptoMiningEvent?.self, forKey: .cryptoMiningEvent)
    {
      try eventTypeCheckAndSet(.cryptoMiningEvent(cryptoMiningEvent))
    }
    if let leakedCredentialEvent = try container.decodeIfPresent(
      LeakedCredentialEvent?.self, forKey: .leakedCredentialEvent)
    {
      try eventTypeCheckAndSet(.leakedCredentialEvent(leakedCredentialEvent))
    }
    if let harmfulContentEvent = try container.decodeIfPresent(
      HarmfulContentEvent?.self, forKey: .harmfulContentEvent)
    {
      try eventTypeCheckAndSet(.harmfulContentEvent(harmfulContentEvent))
    }
    if let reinstatementEvent = try container.decodeIfPresent(
      ReinstatementEvent?.self, forKey: .reinstatementEvent)
    {
      try eventTypeCheckAndSet(.reinstatementEvent(reinstatementEvent))
    }
    if let decisionEscalationEvent = try container.decodeIfPresent(
      DecisionEscalationEvent?.self, forKey: .decisionEscalationEvent)
    {
      try eventTypeCheckAndSet(.decisionEscalationEvent(decisionEscalationEvent))
    }
    if let intrusionAttemptEvent = try container.decodeIfPresent(
      IntrusionAttemptEvent?.self, forKey: .intrusionAttemptEvent)
    {
      try eventTypeCheckAndSet(.intrusionAttemptEvent(intrusionAttemptEvent))
    }
    self.eventType = eventType
  }

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

    if let choice = self.eventType {
      switch choice {
      case .cryptoMiningEvent(let value):
        try container.encode(value, forKey: .cryptoMiningEvent)
      case .leakedCredentialEvent(let value):
        try container.encode(value, forKey: .leakedCredentialEvent)
      case .harmfulContentEvent(let value):
        try container.encode(value, forKey: .harmfulContentEvent)
      case .reinstatementEvent(let value):
        try container.encode(value, forKey: .reinstatementEvent)
      case .decisionEscalationEvent(let value):
        try container.encode(value, forKey: .decisionEscalationEvent)
      case .intrusionAttemptEvent(let value):
        try container.encode(value, forKey: .intrusionAttemptEvent)
      }
    }
  }

  /// Indicates the type of abuse detected on the monitored resource.
  public enum DetectionType: Codable, Equatable, Sendable {
    /// Default/unspecified abuse detection type.
    case unspecified
    /// The monitored resource is used to mine cryptocurrencies.
    case cryptoMining
    /// The monitored resource's credentials have accidentally been leaked on the
    /// internet.
    case leakedCredentials
    /// The monitored resource is used for phishing attacks.
    case phishing
    /// The monitored resource is associated with content that is infected or
    /// infects users with malicious software.
    case malware
    /// No abuse is detected on the monitored resource, but its abuse state may
    /// have been updated.
    case noAbuse
    /// The monitored resource is believed to be attempting to intrude upon
    /// third-party resources.
    case intrusionAttempt
    /// 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 .cryptoMining: return 1
      case .leakedCredentials: return 2
      case .phishing: return 3
      case .malware: return 4
      case .noAbuse: return 5
      case .intrusionAttempt: return 6
      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 "DETECTION_TYPE_UNSPECIFIED"
      case .cryptoMining: return "CRYPTO_MINING"
      case .leakedCredentials: return "LEAKED_CREDENTIALS"
      case .phishing: return "PHISHING"
      case .malware: return "MALWARE"
      case .noAbuse: return "NO_ABUSE"
      case .intrusionAttempt: return "INTRUSION_ATTEMPT"
      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:DetectionType/unknownStringValue(_:)).
    public init(stringValue: Swift.String) {
      switch stringValue {
      case "DETECTION_TYPE_UNSPECIFIED": self = .unspecified
      case "CRYPTO_MINING": self = .cryptoMining
      case "LEAKED_CREDENTIALS": self = .leakedCredentials
      case "PHISHING": self = .phishing
      case "MALWARE": self = .malware
      case "NO_ABUSE": self = .noAbuse
      case "INTRUSION_ATTEMPT": self = .intrusionAttempt
      default: self = .unknownStringValue(stringValue)
      }
    }

    /// Initialize from an integer value.
    ///
    /// If the value is unknown, this initializes to [`unknownIntValue`](doc:DetectionType/unknownIntValue(_:)).
    public init(intValue: Int) {
      switch intValue {
      case 0: self = .unspecified
      case 1: self = .cryptoMining
      case 2: self = .leakedCredentials
      case 3: self = .phishing
      case 4: self = .malware
      case 5: self = .noAbuse
      case 6: self = .intrusionAttempt
      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 .cryptoMining: return try container.encode(1)
      case .leakedCredentials: return try container.encode(2)
      case .phishing: return try container.encode(3)
      case .malware: return try container.encode(4)
      case .noAbuse: return try container.encode(5)
      case .intrusionAttempt: return try container.encode(6)
      case .unknownIntValue(let v): return try container.encode(v)
      case .unknownStringValue(let v): return try container.encode(v)
      }
    }
  }

  /// Indicates any action taken on the monitored resource due to abuse
  /// detection.
  public enum ActionType: Codable, Equatable, Sendable {
    /// The monitored resource state is unspecified.
    case unspecified
    /// The owner of the monitored resource needs to be notified about a finding.
    case notify
    /// The associated cloud project has been suspended.
    case projectSuspension
    /// The monitored resource has been reinstated.
    case reinstate
    /// The owner of the monitored resource needs to be warned about abusive
    /// behavior. This notification could lead to future enforcements if remedial
    /// actions are not taken. This action should not be confused with NOTIFY.
    case warn
    /// The resource (eg: VM) has been suspended.
    case resourceSuspension
    /// 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 .notify: return 1
      case .projectSuspension: return 2
      case .reinstate: return 3
      case .warn: return 4
      case .resourceSuspension: return 5
      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 "ACTION_TYPE_UNSPECIFIED"
      case .notify: return "NOTIFY"
      case .projectSuspension: return "PROJECT_SUSPENSION"
      case .reinstate: return "REINSTATE"
      case .warn: return "WARN"
      case .resourceSuspension: return "RESOURCE_SUSPENSION"
      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:ActionType/unknownStringValue(_:)).
    public init(stringValue: Swift.String) {
      switch stringValue {
      case "ACTION_TYPE_UNSPECIFIED": self = .unspecified
      case "NOTIFY": self = .notify
      case "PROJECT_SUSPENSION": self = .projectSuspension
      case "REINSTATE": self = .reinstate
      case "WARN": self = .warn
      case "RESOURCE_SUSPENSION": self = .resourceSuspension
      default: self = .unknownStringValue(stringValue)
      }
    }

    /// Initialize from an integer value.
    ///
    /// If the value is unknown, this initializes to [`unknownIntValue`](doc:ActionType/unknownIntValue(_:)).
    public init(intValue: Int) {
      switch intValue {
      case 0: self = .unspecified
      case 1: self = .notify
      case 2: self = .projectSuspension
      case 3: self = .reinstate
      case 4: self = .warn
      case 5: self = .resourceSuspension
      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 .notify: return try container.encode(1)
      case .projectSuspension: return try container.encode(2)
      case .reinstate: return try container.encode(3)
      case .warn: return try container.encode(4)
      case .resourceSuspension: return try container.encode(5)
      case .unknownIntValue(let v): return try container.encode(v)
      case .unknownStringValue(let v): return try container.encode(v)
      }
    }
  }

  /// REQUIRED Contains addiional metadata about the detected abuse event.
  public enum OneOf_EventType: Codable, Equatable, Sendable {
    /// Information about a cryptocurrency mining event observed on the monitored
    /// resource.
    indirect case cryptoMiningEvent(CryptoMiningEvent?)
    /// Information about the leaked client credentials observed on the monitored
    /// resource.
    indirect case leakedCredentialEvent(LeakedCredentialEvent?)
    /// Information about the phishing/malware URI(s) associated with the
    /// monitored resource.
    indirect case harmfulContentEvent(HarmfulContentEvent?)
    /// Information about the reinstatement issued on the monitored resource.
    indirect case reinstatementEvent(ReinstatementEvent?)
    /// Information about the escalation of enforcement action on the monitored
    /// resource.
    indirect case decisionEscalationEvent(DecisionEscalationEvent?)
    /// Information about an intrusion attempt event.
    indirect case intrusionAttemptEvent(IntrusionAttemptEvent?)
  }

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