using CodexProviderSync.Core; namespace CodexProviderSync.Mac; internal static class MacDisplayFormatter { public static string FormatStatus(StatusSnapshot status, string language) { if (!MacUiText.IsChinese(language)) { return TextFormatter.FormatStatus(status); } List lines = [ $"Codex Home: {status.CodexHome}", $"当前 Provider: {status.CurrentProvider.Provider}{(status.CurrentProvider.Implicit ? "(隐式默认)" : string.Empty)}", $"配置中的 Provider: {string.Join(", ", status.ConfiguredProviders)}", $"备份: {status.BackupSummary.Count}({FormatBytes(status.BackupSummary.TotalBytes)})", $"备份目录: {status.BackupRoot}", string.Empty, "Rollout 文件:", $" sessions: {FormatCounts(status.RolloutCounts.Sessions)}", $" archived_sessions: {FormatCounts(status.RolloutCounts.ArchivedSessions)}", $" encrypted_content sessions: {FormatCounts(status.EncryptedContentCounts.Sessions)}", $" encrypted_content archived_sessions: {FormatCounts(status.EncryptedContentCounts.ArchivedSessions)}", string.Empty, "SQLite 状态:" ]; List rolloutNotes = []; if (status.LockedRolloutFiles.Count > 0) { rolloutNotes.Add($" 状态扫描时跳过 locked rollout 文件: {status.LockedRolloutFiles.Count}"); } if (status.UnreadableRolloutFiles.Count > 0) { rolloutNotes.Add($" 状态扫描时跳过不可读 rollout 文件: {status.UnreadableRolloutFiles.Count}"); } if (!string.IsNullOrWhiteSpace(status.EncryptedContentWarning)) { rolloutNotes.Add($" {status.EncryptedContentWarning}"); } lines.InsertRange(11, rolloutNotes); if (status.StateDbLocation is not null) { string legacyNote = status.StateDbLocation.Source == "legacy-root" ? " (legacy root)" : string.Empty; lines.Add($" database: {status.StateDbLocation.Path}{legacyNote}"); } else { lines.Add(" database: not found (checked sqlite/state_5.sqlite, state_5.sqlite)"); } if (status.SqliteCounts?.Unreadable == true) { lines.Add($" {status.SqliteCounts.Error ?? "state_5.sqlite 损坏或不可读"}"); } else if (status.SqliteCounts is null) { lines.Add(" 未找到 state_5.sqlite"); } else { lines.Add($" sessions: {FormatCounts(status.SqliteCounts.Sessions)}"); lines.Add($" archived_sessions: {FormatCounts(status.SqliteCounts.ArchivedSessions)}"); if (status.SqliteRepairStats?.UserEventRowsNeedingRepair > 0) { lines.Add($" 需要修复的 user-event 标记: {status.SqliteRepairStats.UserEventRowsNeedingRepair}"); } if (status.SqliteRepairStats?.CwdRowsNeedingRepair > 0) { lines.Add($" 需要修复的 cwd 路径: {status.SqliteRepairStats.CwdRowsNeedingRepair}"); } } if (status.ProjectThreadVisibility.Count > 0) { lines.Add(string.Empty); lines.Add("项目可见性:"); foreach (ProjectThreadVisibility project in status.ProjectThreadVisibility) { string rankText = string.IsNullOrWhiteSpace(project.RankPreview) ? "(无)" : project.RankPreview; lines.Add( $" {project.Root}: interactive {project.InteractiveThreads}, 首屏 {project.FirstPageThreads}/50, ranks {rankText}, 精确 cwd {project.ExactCwdMatches}/{project.InteractiveThreads}, 原始 cwd 行 {project.VerbatimCwdRows}, providers {FormatCounts(project.ProviderCounts)}"); } } return string.Join(Environment.NewLine, lines); } public static string FormatSyncResult(SyncResult result, string label, string language) { if (!MacUiText.IsChinese(language)) { return TextFormatter.FormatSyncResult(result, label); } List lines = [ $"{label} provider: {result.TargetProvider}", $"Codex Home: {result.CodexHome}", $"备份: {result.BackupDir}", $"已更新 rollout 文件: {result.ChangedSessionFiles}", $"已更新 SQLite 行: {result.SqliteRowsUpdated}{(result.SqlitePresent ? string.Empty : "(未找到 state_5.sqlite)")}" ]; if (result.SqliteUserEventRowsUpdated > 0) { lines.Add($"已更新 SQLite user-event 标记: {result.SqliteUserEventRowsUpdated}"); } if (result.SqliteCwdRowsUpdated > 0) { lines.Add($"已更新 SQLite cwd 路径: {result.SqliteCwdRowsUpdated}"); } if (result.UpdatedWorkspaceRoots > 0) { lines.Add($"已更新 workspace roots: {result.UpdatedWorkspaceRoots}"); } if (result.SkippedLockedRolloutFiles.Count > 0) { string preview = string.Join(", ", result.SkippedLockedRolloutFiles.Take(5)); int extraCount = result.SkippedLockedRolloutFiles.Count - Math.Min(result.SkippedLockedRolloutFiles.Count, 5); lines.Add($"跳过 locked rollout 文件: {result.SkippedLockedRolloutFiles.Count}"); lines.Add($"Locked 文件: {preview}{(extraCount > 0 ? $"(另有 {extraCount} 个)" : string.Empty)}"); } if (result.SkippedUnreadableRolloutFiles.Count > 0) { string preview = string.Join(", ", result.SkippedUnreadableRolloutFiles.Take(5)); int extraCount = result.SkippedUnreadableRolloutFiles.Count - Math.Min(result.SkippedUnreadableRolloutFiles.Count, 5); lines.Add($"跳过不可读 rollout 文件: {result.SkippedUnreadableRolloutFiles.Count}"); lines.Add($"不可读文件: {preview}{(extraCount > 0 ? $"(另有 {extraCount} 个)" : string.Empty)}"); } if (!string.IsNullOrWhiteSpace(result.EncryptedContentWarning)) { lines.Add(result.EncryptedContentWarning); } if (result.AutoPruneResult is not null) { lines.Add( $"备份清理: 删除 {result.AutoPruneResult.DeletedCount}, 剩余 {result.AutoPruneResult.RemainingCount}, 释放 {FormatBytes(result.AutoPruneResult.FreedBytes)}"); } if (!string.IsNullOrWhiteSpace(result.AutoPruneWarning)) { lines.Add($"备份清理警告: {result.AutoPruneWarning}"); } return string.Join(Environment.NewLine, lines); } public static string FormatRestoreResult(RestoreResult result, string language) { if (!MacUiText.IsChinese(language)) { return TextFormatter.FormatRestoreResult(result); } List lines = [ $"已从备份恢复: {result.BackupDir}", $"Codex Home: {result.CodexHome}", $"备份时的 Provider: {result.TargetProvider}", $"备份的 rollout 文件数量: {result.ChangedSessionFiles}" ]; if (result.CreatedAt is not null) { lines.Add($"备份创建时间: {result.CreatedAt:O}"); } return string.Join(Environment.NewLine, lines); } public static string FormatBackupPruneResult(BackupPruneResult result, string language) { if (!MacUiText.IsChinese(language)) { return TextFormatter.FormatBackupPruneResult(result); } return string.Join(Environment.NewLine, new[] { $"备份根目录: {result.BackupRoot}", $"已删除备份: {result.DeletedCount}", $"剩余备份: {result.RemainingCount}", $"释放空间: {FormatBytes(result.FreedBytes)}" }); } public static string FormatProviderSources(ProviderOption option, string language) { return string.Join(", ", option.Sources.Select(source => source switch { ProviderSource.Config => MacUiText.IsChinese(language) ? "配置" : "Config", ProviderSource.Rollout => "Rollout", ProviderSource.Sqlite => "SQLite", ProviderSource.Manual => MacUiText.IsChinese(language) ? "手动" : "Manual", _ => source.ToString() })); } private static string FormatCounts(Dictionary counts) { return counts.Count == 0 ? "(none)" : string.Join(", ", counts.OrderBy(pair => pair.Key, StringComparer.Ordinal).Select(pair => $"{pair.Key}: {pair.Value}")); } private static string FormatBytes(long bytes) { string[] units = ["B", "KB", "MB", "GB", "TB"]; double value = bytes; int unitIndex = 0; while (value >= 1024 && unitIndex < units.Length - 1) { value /= 1024; unitIndex += 1; } return unitIndex == 0 ? $"{bytes} B" : $"{value:0.##} {units[unitIndex]}"; } }