import Foundation public struct AlibabaCodingPlanUsageSnapshot: Sendable { public let planName: String? public let fiveHourUsedQuota: Int? public let fiveHourTotalQuota: Int? public let fiveHourNextRefreshTime: Date? public let weeklyUsedQuota: Int? public let weeklyTotalQuota: Int? public let weeklyNextRefreshTime: Date? public let monthlyUsedQuota: Int? public let monthlyTotalQuota: Int? public let monthlyNextRefreshTime: Date? public let updatedAt: Date public init( planName: String?, fiveHourUsedQuota: Int?, fiveHourTotalQuota: Int?, fiveHourNextRefreshTime: Date?, weeklyUsedQuota: Int?, weeklyTotalQuota: Int?, weeklyNextRefreshTime: Date?, monthlyUsedQuota: Int?, monthlyTotalQuota: Int?, monthlyNextRefreshTime: Date?, updatedAt: Date) { self.planName = planName self.fiveHourUsedQuota = fiveHourUsedQuota self.fiveHourTotalQuota = fiveHourTotalQuota self.fiveHourNextRefreshTime = fiveHourNextRefreshTime self.weeklyUsedQuota = weeklyUsedQuota self.weeklyTotalQuota = weeklyTotalQuota self.weeklyNextRefreshTime = weeklyNextRefreshTime self.monthlyUsedQuota = monthlyUsedQuota self.monthlyTotalQuota = monthlyTotalQuota self.monthlyNextRefreshTime = monthlyNextRefreshTime self.updatedAt = updatedAt }} extension AlibabaCodingPlanUsageSnapshot { public func toUsageSnapshot() -> UsageSnapshot { let primaryPercent = Self.usedPercent(used: self.fiveHourUsedQuota, total: self.fiveHourTotalQuota) let secondaryPercent = Self.usedPercent(used: self.weeklyUsedQuota, total: self.weeklyTotalQuota) let tertiaryPercent = Self.usedPercent(used: self.monthlyUsedQuota, total: self.monthlyTotalQuota) let primary: RateWindow? = if let primaryPercent { RateWindow( usedPercent: primaryPercent, windowMinutes: 5 * 60, resetsAt: Self.normalizedFiveHourReset( self.fiveHourNextRefreshTime, updatedAt: self.updatedAt), resetDescription: Self.usageDetail(used: self.fiveHourUsedQuota, total: self.fiveHourTotalQuota)) } else { nil } let secondary: RateWindow? = if let secondaryPercent { RateWindow( usedPercent: secondaryPercent, windowMinutes: 7 * 24 * 60, resetsAt: self.weeklyNextRefreshTime, resetDescription: Self.usageDetail(used: self.weeklyUsedQuota, total: self.weeklyTotalQuota)) } else { nil } let tertiary: RateWindow? = if let tertiaryPercent { RateWindow( usedPercent: tertiaryPercent, windowMinutes: 30 * 24 * 60, resetsAt: self.monthlyNextRefreshTime, resetDescription: Self.usageDetail(used: self.monthlyUsedQuota, total: self.monthlyTotalQuota)) } else { nil } let loginMethod = self.planName?.trimmingCharacters(in: .whitespacesAndNewlines) let identity = ProviderIdentitySnapshot( providerID: .alibaba, accountEmail: nil, accountOrganization: nil, loginMethod: loginMethod) return UsageSnapshot( primary: primary, secondary: secondary, tertiary: tertiary, providerCost: nil, updatedAt: self.updatedAt, identity: identity) } private static func usedPercent(used: Int?, total: Int?) -> Double? { guard let used, let total, total > 0 else { return nil } let normalizedUsed = max(0, min(used, total)) return Double(normalizedUsed) / Double(total) * 100 } private static func limitDescription(total: Int?, label: String) -> String? { guard let total, total > 0 else { return nil } return "\(total) requests / \(label)" } private static func usageDetail(used: Int?, total: Int?) -> String? { guard let used, let total, total > 0 else { return nil } return "\(used) / \(total) used" } private static func normalizedFiveHourReset(_ raw: Date?, updatedAt: Date) -> Date? { guard let raw else { return nil } if raw.timeIntervalSince(updatedAt) >= 60 { return raw } let shifted = raw.addingTimeInterval(TimeInterval(5 * 60 * 60)) if shifted.timeIntervalSince(updatedAt) >= 60 { return shifted } return updatedAt.addingTimeInterval(TimeInterval(5 * 60 * 60)) }}
import Foundation
public struct AlibabaCodingPlanUsageSnapshot: Sendable {
public let planName: String?
public let fiveHourUsedQuota: Int?
public let fiveHourTotalQuota: Int?
public let fiveHourNextRefreshTime: Date?
public let weeklyUsedQuota: Int?
public let weeklyTotalQuota: Int?
public let weeklyNextRefreshTime: Date?
public let monthlyUsedQuota: Int?
public let monthlyTotalQuota: Int?
public let monthlyNextRefreshTime: Date?
public let updatedAt: Date
public init(
planName: String?,
fiveHourUsedQuota: Int?,
fiveHourTotalQuota: Int?,
fiveHourNextRefreshTime: Date?,
weeklyUsedQuota: Int?,
weeklyTotalQuota: Int?,
weeklyNextRefreshTime: Date?,
monthlyUsedQuota: Int?,
monthlyTotalQuota: Int?,
monthlyNextRefreshTime: Date?,
updatedAt: Date)
{
self.planName = planName
self.fiveHourUsedQuota = fiveHourUsedQuota
self.fiveHourTotalQuota = fiveHourTotalQuota
self.fiveHourNextRefreshTime = fiveHourNextRefreshTime
self.weeklyUsedQuota = weeklyUsedQuota
self.weeklyTotalQuota = weeklyTotalQuota
self.weeklyNextRefreshTime = weeklyNextRefreshTime
self.monthlyUsedQuota = monthlyUsedQuota
self.monthlyTotalQuota = monthlyTotalQuota
self.monthlyNextRefreshTime = monthlyNextRefreshTime
self.updatedAt = updatedAt
}
}
extension AlibabaCodingPlanUsageSnapshot {
public func toUsageSnapshot() -> UsageSnapshot {
let primaryPercent = Self.usedPercent(used: self.fiveHourUsedQuota, total: self.fiveHourTotalQuota)
let secondaryPercent = Self.usedPercent(used: self.weeklyUsedQuota, total: self.weeklyTotalQuota)
let tertiaryPercent = Self.usedPercent(used: self.monthlyUsedQuota, total: self.monthlyTotalQuota)
let primary: RateWindow? = if let primaryPercent {
RateWindow(
usedPercent: primaryPercent,
windowMinutes: 5 * 60,
resetsAt: Self.normalizedFiveHourReset(
self.fiveHourNextRefreshTime,
updatedAt: self.updatedAt),
resetDescription: Self.usageDetail(used: self.fiveHourUsedQuota, total: self.fiveHourTotalQuota))
} else {
nil
}
let secondary: RateWindow? = if let secondaryPercent {
RateWindow(
usedPercent: secondaryPercent,
windowMinutes: 7 * 24 * 60,
resetsAt: self.weeklyNextRefreshTime,
resetDescription: Self.usageDetail(used: self.weeklyUsedQuota, total: self.weeklyTotalQuota))
} else {
nil
}
let tertiary: RateWindow? = if let tertiaryPercent {
RateWindow(
usedPercent: tertiaryPercent,
windowMinutes: 30 * 24 * 60,
resetsAt: self.monthlyNextRefreshTime,
resetDescription: Self.usageDetail(used: self.monthlyUsedQuota, total: self.monthlyTotalQuota))
} else {
nil
}
let loginMethod = self.planName?.trimmingCharacters(in: .whitespacesAndNewlines)
let identity = ProviderIdentitySnapshot(
providerID: .alibaba,
accountEmail: nil,
accountOrganization: nil,
loginMethod: loginMethod)
return UsageSnapshot(
primary: primary,
secondary: secondary,
tertiary: tertiary,
providerCost: nil,
updatedAt: self.updatedAt,
identity: identity)
}
private static func usedPercent(used: Int?, total: Int?) -> Double? {
guard let used, let total, total > 0 else { return nil }
let normalizedUsed = max(0, min(used, total))
return Double(normalizedUsed) / Double(total) * 100
}
private static func limitDescription(total: Int?, label: String) -> String? {
guard let total, total > 0 else { return nil }
return "\(total) requests / \(label)"
}
private static func usageDetail(used: Int?, total: Int?) -> String? {
guard let used, let total, total > 0 else { return nil }
return "\(used) / \(total) used"
}
private static func normalizedFiveHourReset(_ raw: Date?, updatedAt: Date) -> Date? {
guard let raw else { return nil }
if raw.timeIntervalSince(updatedAt) >= 60 {
return raw
}
let shifted = raw.addingTimeInterval(TimeInterval(5 * 60 * 60))
if shifted.timeIntervalSince(updatedAt) >= 60 {
return shifted
}
return updatedAt.addingTimeInterval(TimeInterval(5 * 60 * 60))
}
}