// Generated by Create API
// https://github.com/CreateAPI/CreateAPI

import Foundation

public struct UserNotificationSchema: Codable, Equatable {
    public var notifications: [Notification]?
    public var notifiedAt: Date

    public struct Notification: Codable, Equatable {
        public var object: Object?
        public var anyJSON: AnyJSON?

        public enum Object: Codable, Equatable {
            case notificationReactSchema(NotificationReactSchema)
            case notificationFollowSchema(NotificationFollowSchema)
            case notificationAnnouncementSchema(NotificationAnnouncementSchema)
            case notificationPersonaSchema(NotificationPersonaSchema)

            public init(from decoder: Decoder) throws {

                struct Discriminator: Decodable {
                    let notificationType: String
                }

                let container = try decoder.singleValueContainer()
                let discriminatorValue = try container.decode(Discriminator.self).notificationType

                switch discriminatorValue {
                case "clip_like": self = .notificationReactSchema(try container.decode(NotificationReactSchema.self))
                case "clip_unlike": self = .notificationReactSchema(try container.decode(NotificationReactSchema.self))
                case "code_redeem": self = .notificationReactSchema(try container.decode(NotificationReactSchema.self))
                case "playlist_like": self = .notificationReactSchema(try container.decode(NotificationReactSchema.self))
                case "playlist_unlike": self = .notificationReactSchema(try container.decode(NotificationReactSchema.self))
                case "scene_like": self = .notificationReactSchema(try container.decode(NotificationReactSchema.self))
                case "scene_unlike": self = .notificationReactSchema(try container.decode(NotificationReactSchema.self))
                case "follow": self = .notificationFollowSchema(try container.decode(NotificationFollowSchema.self))
                case "unfollow": self = .notificationFollowSchema(try container.decode(NotificationFollowSchema.self))
                case "announcement": self = .notificationAnnouncementSchema(try container.decode(NotificationAnnouncementSchema.self))
                case "persona_favorite": self = .notificationPersonaSchema(try container.decode(NotificationPersonaSchema.self))
                case "persona_follow": self = .notificationPersonaSchema(try container.decode(NotificationPersonaSchema.self))
                case "persona_used": self = .notificationPersonaSchema(try container.decode(NotificationPersonaSchema.self))

                default:
                    throw DecodingError.dataCorruptedError(
                        in: container,
                        debugDescription: "Discriminator value '\(discriminatorValue)' does not match any expected values (clip_like, clip_unlike, code_redeem, playlist_like, playlist_unlike, scene_like, scene_unlike, follow, unfollow, announcement, persona_favorite, persona_follow, persona_used)."
                    )
                }
            }

            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                switch self {
                case .notificationReactSchema(let value): try container.encode(value)
                case .notificationFollowSchema(let value): try container.encode(value)
                case .notificationAnnouncementSchema(let value): try container.encode(value)
                case .notificationPersonaSchema(let value): try container.encode(value)
                }
            }
        }

        public init(object: Object? = nil, anyJSON: AnyJSON? = nil) {
            self.object = object
            self.anyJSON = anyJSON
        }

        public init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            self.object = try? container.decode(Object.self)
            self.anyJSON = try? container.decode(AnyJSON.self)
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            if let value = object { try container.encode(value) }
            if let value = anyJSON { try container.encode(value) }
        }
    }

    public init(notifications: [Notification]? = nil, notifiedAt: Date) {
        self.notifications = notifications
        self.notifiedAt = notifiedAt
    }
}
