///
/// Copyright (c) 2016 Dropbox, Inc. All rights reserved.
///
/// Auto-generated by Stone, do not modify.
///

import Foundation

/// Datatypes and serializers for the team_common namespace
open class TeamCommon {
    /// The group type determines how a group is managed.
    public enum GroupManagementType: CustomStringConvertible {
        /// A group which is managed by selected users.
        case userManaged
        /// A group which is managed by team admins only.
        case companyManaged
        /// A group which is managed automatically by Dropbox.
        case systemManaged
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(GroupManagementTypeSerializer().serialize(self)))"
        }
    }
    open class GroupManagementTypeSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: GroupManagementType) -> JSON {
            switch value {
                case .userManaged:
                    var d = [String: JSON]()
                    d[".tag"] = .str("user_managed")
                    return .dictionary(d)
                case .companyManaged:
                    var d = [String: JSON]()
                    d[".tag"] = .str("company_managed")
                    return .dictionary(d)
                case .systemManaged:
                    var d = [String: JSON]()
                    d[".tag"] = .str("system_managed")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> GroupManagementType {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "user_managed":
                            return GroupManagementType.userManaged
                        case "company_managed":
                            return GroupManagementType.companyManaged
                        case "system_managed":
                            return GroupManagementType.systemManaged
                        case "other":
                            return GroupManagementType.other
                        default:
                            return GroupManagementType.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// Information about a group.
    open class GroupSummary: CustomStringConvertible {
        /// (no description)
        public let groupName: String
        /// (no description)
        public let groupId: String
        /// External ID of group. This is an arbitrary ID that an admin can attach to a group.
        public let groupExternalId: String?
        /// The number of members in the group.
        public let memberCount: UInt32?
        /// Who is allowed to manage the group.
        public let groupManagementType: TeamCommon.GroupManagementType
        public init(groupName: String, groupId: String, groupManagementType: TeamCommon.GroupManagementType, groupExternalId: String? = nil, memberCount: UInt32? = nil) {
            stringValidator()(groupName)
            self.groupName = groupName
            stringValidator()(groupId)
            self.groupId = groupId
            nullableValidator(stringValidator())(groupExternalId)
            self.groupExternalId = groupExternalId
            nullableValidator(comparableValidator())(memberCount)
            self.memberCount = memberCount
            self.groupManagementType = groupManagementType
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(GroupSummarySerializer().serialize(self)))"
        }
    }
    open class GroupSummarySerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: GroupSummary) -> JSON {
            let output = [ 
            "group_name": Serialization._StringSerializer.serialize(value.groupName),
            "group_id": Serialization._StringSerializer.serialize(value.groupId),
            "group_management_type": TeamCommon.GroupManagementTypeSerializer().serialize(value.groupManagementType),
            "group_external_id": NullableSerializer(Serialization._StringSerializer).serialize(value.groupExternalId),
            "member_count": NullableSerializer(Serialization._UInt32Serializer).serialize(value.memberCount),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> GroupSummary {
            switch json {
                case .dictionary(let dict):
                    let groupName = Serialization._StringSerializer.deserialize(dict["group_name"] ?? .null)
                    let groupId = Serialization._StringSerializer.deserialize(dict["group_id"] ?? .null)
                    let groupManagementType = TeamCommon.GroupManagementTypeSerializer().deserialize(dict["group_management_type"] ?? .null)
                    let groupExternalId = NullableSerializer(Serialization._StringSerializer).deserialize(dict["group_external_id"] ?? .null)
                    let memberCount = NullableSerializer(Serialization._UInt32Serializer).deserialize(dict["member_count"] ?? .null)
                    return GroupSummary(groupName: groupName, groupId: groupId, groupManagementType: groupManagementType, groupExternalId: groupExternalId, memberCount: memberCount)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

    /// The group type determines how a group is created and managed.
    public enum GroupType: CustomStringConvertible {
        /// A group to which team members are automatically added. Applicable to team folders
        /// https://www.dropbox.com/help/986 only.
        case team
        /// A group is created and managed by a user.
        case userManaged
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(GroupTypeSerializer().serialize(self)))"
        }
    }
    open class GroupTypeSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: GroupType) -> JSON {
            switch value {
                case .team:
                    var d = [String: JSON]()
                    d[".tag"] = .str("team")
                    return .dictionary(d)
                case .userManaged:
                    var d = [String: JSON]()
                    d[".tag"] = .str("user_managed")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> GroupType {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "team":
                            return GroupType.team
                        case "user_managed":
                            return GroupType.userManaged
                        case "other":
                            return GroupType.other
                        default:
                            return GroupType.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// The type of the space limit imposed on a team member.
    public enum MemberSpaceLimitType: CustomStringConvertible {
        /// The team member does not have imposed space limit.
        case off
        /// The team member has soft imposed space limit - the limit is used for display and for notifications.
        case alertOnly
        /// The team member has hard imposed space limit - Dropbox file sync will stop after the limit is reached.
        case stopSync
        /// An unspecified error.
        case other

        public var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(MemberSpaceLimitTypeSerializer().serialize(self)))"
        }
    }
    open class MemberSpaceLimitTypeSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: MemberSpaceLimitType) -> JSON {
            switch value {
                case .off:
                    var d = [String: JSON]()
                    d[".tag"] = .str("off")
                    return .dictionary(d)
                case .alertOnly:
                    var d = [String: JSON]()
                    d[".tag"] = .str("alert_only")
                    return .dictionary(d)
                case .stopSync:
                    var d = [String: JSON]()
                    d[".tag"] = .str("stop_sync")
                    return .dictionary(d)
                case .other:
                    var d = [String: JSON]()
                    d[".tag"] = .str("other")
                    return .dictionary(d)
            }
        }
        open func deserialize(_ json: JSON) -> MemberSpaceLimitType {
            switch json {
                case .dictionary(let d):
                    let tag = Serialization.getTag(d)
                    switch tag {
                        case "off":
                            return MemberSpaceLimitType.off
                        case "alert_only":
                            return MemberSpaceLimitType.alertOnly
                        case "stop_sync":
                            return MemberSpaceLimitType.stopSync
                        case "other":
                            return MemberSpaceLimitType.other
                        default:
                            return MemberSpaceLimitType.other
                    }
                default:
                    fatalError("Failed to deserialize")
            }
        }
    }

    /// Time range.
    open class TimeRange: CustomStringConvertible {
        /// Optional starting time (inclusive).
        public let startTime: Date?
        /// Optional ending time (exclusive).
        public let endTime: Date?
        public init(startTime: Date? = nil, endTime: Date? = nil) {
            self.startTime = startTime
            self.endTime = endTime
        }
        open var description: String {
            return "\(SerializeUtil.prepareJSONForSerialization(TimeRangeSerializer().serialize(self)))"
        }
    }
    open class TimeRangeSerializer: JSONSerializer {
        public init() { }
        open func serialize(_ value: TimeRange) -> JSON {
            let output = [ 
            "start_time": NullableSerializer(NSDateSerializer("%Y-%m-%dT%H:%M:%SZ")).serialize(value.startTime),
            "end_time": NullableSerializer(NSDateSerializer("%Y-%m-%dT%H:%M:%SZ")).serialize(value.endTime),
            ]
            return .dictionary(output)
        }
        open func deserialize(_ json: JSON) -> TimeRange {
            switch json {
                case .dictionary(let dict):
                    let startTime = NullableSerializer(NSDateSerializer("%Y-%m-%dT%H:%M:%SZ")).deserialize(dict["start_time"] ?? .null)
                    let endTime = NullableSerializer(NSDateSerializer("%Y-%m-%dT%H:%M:%SZ")).deserialize(dict["end_time"] ?? .null)
                    return TimeRange(startTime: startTime, endTime: endTime)
                default:
                    fatalError("Type error deserializing")
            }
        }
    }

}
