using System; using System.Collections.Generic; using System.IO; using System.Xml.Serialization; namespace Housing.Services { // XML 직렬화를 위한 데이터 컨테이너 클래스 정의 [XmlRoot("LoginHistory")] public class LoginHistoryData { [XmlElement("Category")] public List Categories { get; set; } = new List(); } public class HistoryCategory { [XmlAttribute("Name")] public string Name { get; set; } [XmlElement("Value")] public List Values { get; set; } = new List(); } public class LoginHistoryStore { private readonly string _filePath; private readonly Dictionary> _history = new Dictionary>(StringComparer.OrdinalIgnoreCase); private LoginHistoryStore(string filePath) { _filePath = filePath; } public static LoginHistoryStore Load(string path) { var store = new LoginHistoryStore(path); store.LoadFromFile(); return store; } public List GetValues(string fieldName) { if (_history.TryGetValue(fieldName, out var list)) { return new List(list); } return new List(); } public void Remember(string fieldName, string value) { if (string.IsNullOrWhiteSpace(value)) return; value = value.Trim(); if (!_history.TryGetValue(fieldName, out var list)) { list = new List(); _history[fieldName] = list; } // 중복 제거 및 맨 앞으로 이동 list.RemoveAll(x => string.Equals(x, value, StringComparison.OrdinalIgnoreCase)); list.Insert(0, value); // 최대 5개 이력 유지 if (list.Count > 5) { list.RemoveRange(5, list.Count - 5); } } public bool Forget(string fieldName, string value) { if (string.IsNullOrWhiteSpace(value)) return false; value = value.Trim(); if (_history.TryGetValue(fieldName, out var list)) { bool removed = list.RemoveAll(x => string.Equals(x, value, StringComparison.OrdinalIgnoreCase)) > 0; return removed; } return false; } public void Save() { try { var dir = Path.GetDirectoryName(_filePath); if (!string.IsNullOrEmpty(dir) && !Directory.Exists(dir)) { Directory.CreateDirectory(dir); } var data = new LoginHistoryData(); foreach (var kvp in _history) { data.Categories.Add(new HistoryCategory { Name = kvp.Key, Values = kvp.Value }); } XmlSerializer serializer = new XmlSerializer(typeof(LoginHistoryData)); using (var sw = new StreamWriter(_filePath)) { serializer.Serialize(sw, data); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[LoginHistoryStore Save Error] {ex.Message}"); } } private void LoadFromFile() { try { if (!File.Exists(_filePath)) return; XmlSerializer serializer = new XmlSerializer(typeof(LoginHistoryData)); using (var sr = new StreamReader(_filePath)) { var data = (LoginHistoryData)serializer.Deserialize(sr); if (data?.Categories != null) { _history.Clear(); foreach (var cat in data.Categories) { if (!string.IsNullOrEmpty(cat.Name)) { _history[cat.Name] = cat.Values ?? new List(); } } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[LoginHistoryStore Load Error] {ex.Message}"); } } } }