import Foundation

/// Ably event types
public enum AblyEvent: Equatable {
    case connected
    case disconnected
    case message(AblyMessage)
    case error(Error)
    
    public static func == (lhs: AblyEvent, rhs: AblyEvent) -> Bool {
        switch (lhs, rhs) {
        case (.connected, .connected), (.disconnected, .disconnected):
            return true
        case (.message(let lhsMsg), .message(let rhsMsg)):
            return lhsMsg == rhsMsg
        case (.error(let lhsError), .error(let rhsError)):
            return lhsError.localizedDescription == rhsError.localizedDescription
        default:
            return false
        }
    }
}

/// Ably message structure
public struct AblyMessage: Equatable, Codable {
    public let id: String?
    public let name: String?
    public let data: String?
    public let timestamp: Int64?
    
    enum CodingKeys: String, CodingKey {
        case id
        case name
        case data
        case timestamp
    }
    
    public init(id: String? = nil, name: String? = nil, data: String? = nil, timestamp: Int64? = nil) {
        self.id = id
        self.name = name
        self.data = data
        self.timestamp = timestamp
    }
}

/// Ably token response from API
public struct AblyTokenResponse: Codable {
    public let token: String
    public let issued: Int64
    public let expires: Int64
    public let clientId: String?
    public let keyName: String?
    public let nonce: String?
    public let mac: String?
    
    enum CodingKeys: String, CodingKey {
        case token
        case issued
        case expires
        case clientId = "client_id"
        case keyName = "key_name"
        case nonce
        case mac
    }
    
    public init(token: String, issued: Int64, expires: Int64, clientId: String? = nil, keyName: String? = nil, nonce: String? = nil, mac: String? = nil) {
        self.token = token
        self.issued = issued
        self.expires = expires
        self.clientId = clientId
        self.keyName = keyName
        self.nonce = nonce
        self.mac = mac
    }
}

