using Aurora; using Aurora.Api; using Aurora.Util.HislogPlus; using Aurora.View; using AuroraUIComponent.Sequence; using AuroraUIComponent.Util.WindowAPI; using Hermes.Functional; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.IO; using System.Linq; using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; using System.Web.UI.WebControls; using System.Windows; using System.Windows.Input; namespace AuroraUIComponent.Views { public class UCCSVLogViewModel : NotifyPropertyChangedBase { IAuroraEnvironment _AuroraEnv; public string LogName { get; } public DataTable CurrentLog { get => _CurrentLog; set => SetProperty(ref _CurrentLog, value); } private DataTable _CurrentLog; public DataTable FileLog { get => _FileLog; set => SetProperty(ref _FileLog, value); } private DataTable _FileLog; public DataTable ViewLog { get => _ViewLog; set => SetProperty(ref _ViewLog, value); } // Invisible할 때에는 업데이트되지 않도록 CurrentLog와 ViewLog를 별도 관리 private DataTable _ViewLog; public ICommand CMD_VisibleChanged { get; set; } public ICommand CMD_Clear { get; set; } public ICommand CMD_RefreshList { get; set; } public ICommand CMD_OpenFolder { get; set; } public string LogDir { get => _LogDir; set => SetProperty(ref _LogDir, value); } private string _LogDir; const string CURRENT_LOG = "Current"; // 현재 로깅중인 파일을 보여줄 때 public bool IsCurrentLogShowing { get => SelectedFile == CURRENT_LOG; } public string SelectedFile { get => _SelectedFile; set { if (SetProperty(ref _SelectedFile, value)) { if (_IsVisible) { UpdateView(); } } } } private string _SelectedFile; private string CurrentLogFileName; public List FileList { get => _FileList; set => SetProperty(ref _FileList, value); } private List _FileList; public UCCSVLogViewModel(IAuroraEnvironment env, string name, string logDir) { _AuroraEnv = env; LogName = name; LogDir = logDir; CMD_VisibleChanged = new DelegateCommand(OnVisibleChanged); CMD_Clear = new DelegateCommand(ClearLog); CMD_RefreshList = new DelegateCommand(RefreshList); CMD_OpenFolder = new DelegateCommand(OpenFolder); GetFileList(); _AuroraEnv.EventObservable.AsObservable(CsvLogSequence.EVENT_NOTIFY_HEADER_ADDED) .Select(x => ((string, string, string))x.Param) // (logItem.Name, logItem.CurLogFileName, logLine) .Where(x => x.Item1 == LogName) .Subscribe(x => { CurrentLogFileName = x.Item2; AddHeader(x.Item3); }); _AuroraEnv.EventObservable.AsObservable(CsvLogSequence.EVENT_NOTIFY_LOG_ADDED) .Select(x => ((string, string, string))x.Param) // (logItem.Name, logItem.CurLogFileName, logLine) .Where(x => x.Item1 == LogName) .Subscribe(x => { CurrentLogFileName = x.Item2; AddLine(x.Item3); }); _AuroraEnv.EventObservable.AsObservable(CsvLogSequence.EVENT_NOTIFY_LOG_FILE_CHANGED) .Select(x => ((string, string, string))x.Param) // (logItem.Name, logItem.CurLogFileName, logLine) .Where(x => x.Item1 == LogName) .Subscribe(x => { CurrentLogFileName = x.Item3; GetFileList(); }); } private void OpenFolder(object obj) { if (!string.IsNullOrEmpty(LogDir) && Directory.Exists(LogDir)) { WindowUtil.OpenOrActivateFolder(LogDir); } } private bool _IsVisible = true; private void OnVisibleChanged(object obj) { if (obj is bool isVisible) { //Log.FuncW("isVisible : " + isVisible); _IsVisible = isVisible; SelectedFile = CURRENT_LOG; UpdateView(); } } private void UpdateView() { if (_IsVisible) { if (SelectedFile == CURRENT_LOG) { ViewLog = CurrentLog; } else { ReadCsv(Path.Combine(LogDir, SelectedFile)); ViewLog = FileLog; } } else { ViewLog = null; } NotifyPropertyChanged(nameof(IsCurrentLogShowing)); } private void GetFileList() { var newList = new List() { CURRENT_LOG, }; if (!string.IsNullOrEmpty(LogDir) && Directory.Exists(LogDir)) { //Directory.GetFiles(LogDir).ToList().ForEach(x => newList.Add(x)); Directory.GetFiles(LogDir, "*.csv", SearchOption.TopDirectoryOnly) .Select(Path.GetFileName) .Where(file => File.Exists(Path.Combine(LogDir, file)) && new FileInfo(Path.Combine(LogDir, file)).Length > 0 && CurrentLogFileName != file) .OrderByDescending(x => x) .ForEach(x => newList.Add(x)); } FileList = newList; } private void RefreshList(object obj) { GetFileList(); SelectedFile = CURRENT_LOG; } private void ClearLog(object obj) { Application.Current.Dispatcher.BeginInvoke( new Action(() => { if (CurrentLog != null) { CurrentLog.Rows.Clear(); } })); } private void AddHeader(string singleLine) { Application.Current.Dispatcher.BeginInvoke( new Action(() => { if (string.IsNullOrEmpty(singleLine)) return; CurrentLog = new DataTable(); // 열 이름 설정 string[] headers = singleLine.Split(','); foreach (var header in headers) { CurrentLog.Columns.Add(header); } })); } private void AddLine(string singleLine) { Application.Current.Dispatcher.BeginInvoke( new Action(() => { if (string.IsNullOrEmpty(singleLine)) return; if (CurrentLog == null) { CurrentLog = new DataTable(); } //// 데이터 추가 var rows = singleLine.Split(','); CurrentLog.Rows.Add(rows); })); } private void ReadCsv(string filePath) { if (SelectedFile == CURRENT_LOG) { return; } try { Application.Current.Dispatcher.BeginInvoke( new Action(() => { if (string.IsNullOrEmpty(filePath)) return; DataTable dataTable = new DataTable(); using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var reader = new StreamReader(stream)) { var line = reader.ReadLine(); if (line == null || string.IsNullOrEmpty(line)) return; // 첫 번째 줄을 읽어 열 이름을 설정 try { string[] headers = line.Split(','); foreach (var header in headers) { if (!dataTable.Columns.Contains(header)) { dataTable.Columns.Add(header); } else { MessageUtil.ShowErrorToast($"Unexpected Error : Duplicated Header : {header}"); } } } catch (IOException ioEx) { MessageUtil.ShowErrorToast($"Reading Header Error : {ioEx.Message}"); } catch (Exception ex) { MessageUtil.ShowErrorToast($"Reading Header Error : {ex.Message}"); } // 나머지 줄을 읽어 데이터 추가 while (!reader.EndOfStream) { var rows = reader.ReadLine().Split(','); dataTable.Rows.Add(rows); } } FileLog = dataTable; })); } catch (IOException ioEx) { MessageBox.Show($"Error reading CSV file: {ioEx.Message}"); } catch (Exception ex) { MessageBox.Show($"Error reading CSV file: {ex.Message}"); } } } }