//
//  FileDummy Sample Swift File
//  Covers structs, classes, protocols, generics, and async/await.
//

import Foundation

// ── Protocols ────────────────────────────────
protocol Identifiable {
    var id: UUID { get }
    var displayName: String { get }
}

protocol Repository {
    associatedtype Entity: Identifiable
    func findAll() async throws -> [Entity]
    func find(byId id: UUID) async throws -> Entity?
}

// ── Data models ──────────────────────────────
struct User: Identifiable, Codable {
    let id: UUID
    var name: String
    var email: String
    var role: Role

    var displayName: String { "\(name) <\(email)>" }

    enum Role: String, Codable {
        case admin, user, guest
    }
}

struct Task: Identifiable, Codable {
    let id: UUID
    var title: String
    var description: String?
    var status: Status
    var assignee: User?

    var displayName: String { title }

    enum Status: String, Codable {
        case pending, inProgress, completed, failed
    }
}

// ── Generic function ─────────────────────────
func filterByRole<T: Identifiable & Codable>(_ items: [T], role: String) -> [T]
    where T == User {
    items.filter { $0.role.rawValue == role }
}

// ── Error handling ───────────────────────────
enum APIError: Error, LocalizedError {
    case notFound(String)
    case validationFailed(String)
    case networkError

    var errorDescription: String? {
        switch self {
        case .notFound(let msg): return "Not found: \(msg)"
        case .validationFailed(let msg): return "Validation failed: \(msg)"
        case .networkError: return "Network error occurred"
        }
    }
}

// ── Async function ───────────────────────────
func fetchUsers() async throws -> [User] {
    let url = URL(string: "https://api.example.com/users")!
    let (data, response) = try await URLSession.shared.data(from: url)

    guard let http = response as? HTTPURLResponse,
          (200...299).contains(http.statusCode) else {
        throw APIError.networkError
    }

    return try JSONDecoder().decode([User].self, from: data)
}

// ── Main ─────────────────────────────────────
let users = [
    User(id: UUID(), name: "Alice", email: "alice@example.com", role: .admin),
    User(id: UUID(), name: "Bob", email: "bob@example.com", role: .user),
]

for user in users {
    print("\(user.displayName) [\(user.role.rawValue)]")
}
