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

import Foundation

public struct FeaturedFeedSchema: Codable, Equatable, Identifiable {
    public var feedMetadata: FeedMetadata?
    public var feedMetadataType: FeedMetadataType?
    public var id: String?
    /// FeedItemEntityType
    public var itemType: FeedItemEntityType
    public var items: [Item]?
    public var link: String?
    public var mobileLink: String?
    public var title: String?

    public struct FeedMetadata: Codable, Equatable {
        /// Feed Metadata
        public var trendingMetadataSchema: TrendingMetadataSchema?
        public var anyJSON: AnyJSON?

        public init(trendingMetadataSchema: TrendingMetadataSchema? = nil, anyJSON: AnyJSON? = nil) {
            self.trendingMetadataSchema = trendingMetadataSchema
            self.anyJSON = anyJSON
        }

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

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

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

        public enum Object: Codable, Equatable {
            case generatedClipSchema(GeneratedClipSchema)
            case playlistMetadataSchema(PlaylistMetadataSchema)
            case styleItemSchema(StyleItemSchema)
            case personaSchema(PersonaSchema)
            case simpleProfileInfoSchema(SimpleProfileInfoSchema)
            case followingFeedItemSchema(FollowingFeedItemSchema)

            public init(from decoder: Decoder) throws {

                struct Discriminator: Decodable {
                    let entityType: String
                }

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

                switch discriminatorValue {
                case "song_schema": self = .generatedClipSchema(try container.decode(GeneratedClipSchema.self))
                case "playlist_schema": self = .playlistMetadataSchema(try container.decode(PlaylistMetadataSchema.self))
                case "style_schema": self = .styleItemSchema(try container.decode(StyleItemSchema.self))
                case "persona_schema": self = .personaSchema(try container.decode(PersonaSchema.self))
                case "simple_profile_schema": self = .simpleProfileInfoSchema(try container.decode(SimpleProfileInfoSchema.self))
                case "following_feed_item_schema": self = .followingFeedItemSchema(try container.decode(FollowingFeedItemSchema.self))

                default:
                    throw DecodingError.dataCorruptedError(
                        in: container,
                        debugDescription: "Discriminator value '\(discriminatorValue)' does not match any expected values (song_schema, playlist_schema, style_schema, persona_schema, simple_profile_schema, following_feed_item_schema)."
                    )
                }
            }

            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                switch self {
                case .generatedClipSchema(let value): try container.encode(value)
                case .playlistMetadataSchema(let value): try container.encode(value)
                case .styleItemSchema(let value): try container.encode(value)
                case .personaSchema(let value): try container.encode(value)
                case .simpleProfileInfoSchema(let value): try container.encode(value)
                case .followingFeedItemSchema(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(feedMetadata: FeedMetadata? = nil, feedMetadataType: FeedMetadataType? = nil, id: String? = nil, itemType: FeedItemEntityType, items: [Item]? = nil, link: String? = nil, mobileLink: String? = nil, title: String? = nil) {
        self.feedMetadata = feedMetadata
        self.feedMetadataType = feedMetadataType
        self.id = id
        self.itemType = itemType
        self.items = items
        self.link = link
        self.mobileLink = mobileLink
        self.title = title
    }
}
