<commit_before>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Data;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Views;
using WeatherAnalysis.App.Model;
using WeatherAnalysis.App.Navigation;
using WeatherAnalysis.Core.Data;
using WeatherAnalysis.Core.Logic;
using WeatherAnalysis.Core.Model;

namespace WeatherAnalysis.App.ViewModel
{
    public class MainViewModel : BaseViewModel
    {
        private readonly IWeatherRecordManager _weatherRecordManager;

        private Location _selectedLocation;
        private DateTime _selectedDate = DateTime.Today;
        private WeatherRecord _selectedWeatherRecord;

        private RelayCommand _selectLocationCommand;
        private RelayCommand _createWeatherRecordsCommand;
        private RelayCommand<WeatherRecord> _buildReportCommand;
        private RelayCommand<WeatherRecord> _removeWeatherRecordCommand;
        
        private readonly object _weatherRecordsSyncRoot = new object();
        public ObservableCollection<WeatherRecord> WeatherRecords { get; private set; }

        public MainViewModel(IWeatherRecordManager weatherRecordManager, INavigationService navigationService, IMessenger messenger)
            : base(navigationService, messenger)
        {
            _weatherRecordManager = weatherRecordManager;

            InitializeWeatherRecordsCollection();
            InitializeEventHandlers();
            Subscribe();
        }

        private void InitializeWeatherRecordsCollection()
        {
            WeatherRecords = new ObservableCollection<WeatherRecord>();
            BindingOperations.EnableCollectionSynchronization(WeatherRecords, _weatherRecordsSyncRoot);
        }

        private void InitializeEventHandlers()
        {
            PropertyChanged += SelectedDateChanged;
        }

        private void SelectedDateChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == SelectedDatePropertyName)
            {
                GetWeatherRecords();
            }
        }

        private void Subscribe()
        {
            Messenger.Register<Location>(this, NewLocationSelected);
            Messenger.Register<IReadOnlyCollection<WeatherRecord>>(this, WeatherRecordsCreated);
        }

        private void NewLocationSelected(Location location)
        {
            if (location == null) return;

            SelectedLocation = location;
            GetWeatherRecords();
        }

        private void WeatherRecordsCreated(IReadOnlyCollection<WeatherRecord> weatherRecords)
        {
            var saveTask = Task.Run(() =>
            {
                foreach (var weatherRecord in weatherRecords)
                {
                    _weatherRecordManager.Save(weatherRecord);
                }
            });

            saveTask.ContinueWith(task => GetWeatherRecords());
        }

        private void GetWeatherRecords()
        {
            if (SelectedLocation == null || !SelectedLocation.Id.HasValue) return;

            StartProgress();
            WeatherRecords.Clear();

            var refreshTask = Task.Run(() => _weatherRecordManager.Get(SelectedLocation.Id.Value, SelectedDate.Date, SelectedDate.Date.AddHours(24)));
            refreshTask.ContinueWith(task => FinishProgress());
            refreshTask.ContinueWith(task =>
            {
                if (task.IsFaulted || task.IsCanceled) return;
                foreach (var weatherRecord in task.Result)
                {
                    WeatherRecords.Add(weatherRecord);
                }
            });
            refreshTask.ContinueWith(DispatchError);
        }

        #region Properties

        public const string SelectedLocationPropertyName = "SelectedLocation";
        public Location SelectedLocation
        {
            get { return _selectedLocation; }
            set { Set(SelectedLocationPropertyName, ref _selectedLocation, value); }
        }

        public const string SelectedDatePropertyName = "SelectedDate";
        public DateTime SelectedDate
        {
            get { return _selectedDate; }
            set { Set(SelectedDatePropertyName, ref _selectedDate, value); }
        }

        public const string SelectedWeatherRecordPropertyName = "SelectedWeatherRecord";
        public WeatherRecord SelectedWeatherRecord
        {
            get { return _selectedWeatherRecord; }
            set { Set(SelectedWeatherRecordPropertyName, ref _selectedWeatherRecord, value); }
        }

        #endregion

        #region Commands

        public RelayCommand SelectLocation
        {
            get
            {
                return _selectLocationCommand ?? (_selectLocationCommand = new RelayCommand(
                    () => NavigationService.NavigateTo(Dialogs.LocationSelect)));
            }
        }

        public RelayCommand CreateWeatherRecords
        {
            get
            {
                return _createWeatherRecordsCommand ?? (_createWeatherRecordsCommand = new RelayCommand(
                    ExecuteCreateWeatherRecords,
                    CanExecuteCreateWeatherRecords));
            }
        }

        private void ExecuteCreateWeatherRecords()
        {
            var parameter = new CreateWeatherRecordsParameter
            {
                Date = SelectedDate,
                Location = SelectedLocation
            };
            NavigationService.NavigateTo(Dialogs.CreateWeatherRecords, parameter);
        }

        private bool CanExecuteCreateWeatherRecords()
        {
            return SelectedLocation != null;
        }

        public RelayCommand<WeatherRecord> BuildReport
        {
            get
            {
                return _buildReportCommand
                    ?? (_buildReportCommand = new RelayCommand<WeatherRecord>(
                        ExecuteBuildReport,
                        record => record != null));
            }
        }

        private void ExecuteBuildReport(WeatherRecord record)
        {
            var b = new FireHazardReportBuilder(_weatherRecordManager);
            var report = b.BuildReport(record);
            NavigationService.NavigateTo(Dialogs.ReportBuilder, report);
        }

        public RelayCommand<WeatherRecord> RemoveWeatherRecord
        {
            get
            {
                return _removeWeatherRecordCommand
                    ?? (_removeWeatherRecordCommand = new RelayCommand<WeatherRecord>(
                        ExecuteRemoveWeatherRecord,
                        record => record != null));
            }
        }

        private void ExecuteRemoveWeatherRecord(WeatherRecord record)
        {
            var removeTask = Task.Run(() => _weatherRecordManager.Delete(record));
            removeTask.ContinueWith(task => GetWeatherRecords());
        }

        #endregion
    }
}<commit_msg>Build report is now async<commit_after>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Data;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging;
using GalaSoft.MvvmLight.Threading;
using GalaSoft.MvvmLight.Views;
using WeatherAnalysis.App.Model;
using WeatherAnalysis.App.Navigation;
using WeatherAnalysis.Core.Data;
using WeatherAnalysis.Core.Logic;
using WeatherAnalysis.Core.Model;

namespace WeatherAnalysis.App.ViewModel
{
    public class MainViewModel : BaseViewModel
    {
        private readonly IWeatherRecordManager _weatherRecordManager;

        private Location _selectedLocation;
        private DateTime _selectedDate = DateTime.Today;
        private WeatherRecord _selectedWeatherRecord;

        private RelayCommand _selectLocationCommand;
        private RelayCommand _createWeatherRecordsCommand;
        private RelayCommand<WeatherRecord> _buildReportCommand;
        private RelayCommand<WeatherRecord> _removeWeatherRecordCommand;
        
        private readonly object _weatherRecordsSyncRoot = new object();
        public ObservableCollection<WeatherRecord> WeatherRecords { get; private set; }

        public MainViewModel(IWeatherRecordManager weatherRecordManager, INavigationService navigationService, IMessenger messenger)
            : base(navigationService, messenger)
        {
            _weatherRecordManager = weatherRecordManager;

            InitializeWeatherRecordsCollection();
            InitializeEventHandlers();
            Subscribe();
        }

        private void InitializeWeatherRecordsCollection()
        {
            WeatherRecords = new ObservableCollection<WeatherRecord>();
            BindingOperations.EnableCollectionSynchronization(WeatherRecords, _weatherRecordsSyncRoot);
        }

        private void InitializeEventHandlers()
        {
            PropertyChanged += SelectedDateChanged;
        }

        private void SelectedDateChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == SelectedDatePropertyName)
            {
                GetWeatherRecords();
            }
        }

        private void Subscribe()
        {
            Messenger.Register<Location>(this, NewLocationSelected);
            Messenger.Register<IReadOnlyCollection<WeatherRecord>>(this, WeatherRecordsCreated);
        }

        private void NewLocationSelected(Location location)
        {
            if (location == null) return;

            SelectedLocation = location;
            GetWeatherRecords();
        }

        private void WeatherRecordsCreated(IReadOnlyCollection<WeatherRecord> weatherRecords)
        {
            var saveTask = Task.Run(() =>
            {
                foreach (var weatherRecord in weatherRecords)
                {
                    _weatherRecordManager.Save(weatherRecord);
                }
            });

            saveTask.ContinueWith(task => GetWeatherRecords());
        }

        private void GetWeatherRecords()
        {
            if (SelectedLocation == null || !SelectedLocation.Id.HasValue) return;

            StartProgress();
            WeatherRecords.Clear();

            var refreshTask = Task.Run(() => _weatherRecordManager.Get(SelectedLocation.Id.Value, SelectedDate.Date, SelectedDate.Date.AddHours(24)));
            refreshTask.ContinueWith(task => FinishProgress());
            refreshTask.ContinueWith(task =>
            {
                if (task.IsFaulted || task.IsCanceled) return;
                foreach (var weatherRecord in task.Result)
                {
                    WeatherRecords.Add(weatherRecord);
                }
            });
            refreshTask.ContinueWith(DispatchError);
        }

        #region Properties

        public const string SelectedLocationPropertyName = "SelectedLocation";
        public Location SelectedLocation
        {
            get { return _selectedLocation; }
            set { Set(SelectedLocationPropertyName, ref _selectedLocation, value); }
        }

        public const string SelectedDatePropertyName = "SelectedDate";
        public DateTime SelectedDate
        {
            get { return _selectedDate; }
            set { Set(SelectedDatePropertyName, ref _selectedDate, value); }
        }

        public const string SelectedWeatherRecordPropertyName = "SelectedWeatherRecord";
        public WeatherRecord SelectedWeatherRecord
        {
            get { return _selectedWeatherRecord; }
            set { Set(SelectedWeatherRecordPropertyName, ref _selectedWeatherRecord, value); }
        }

        #endregion

        #region Commands

        public RelayCommand SelectLocation
        {
            get
            {
                return _selectLocationCommand ?? (_selectLocationCommand = new RelayCommand(
                    () => NavigationService.NavigateTo(Dialogs.LocationSelect)));
            }
        }

        public RelayCommand CreateWeatherRecords
        {
            get
            {
                return _createWeatherRecordsCommand ?? (_createWeatherRecordsCommand = new RelayCommand(
                    ExecuteCreateWeatherRecords,
                    CanExecuteCreateWeatherRecords));
            }
        }

        private void ExecuteCreateWeatherRecords()
        {
            var parameter = new CreateWeatherRecordsParameter
            {
                Date = SelectedDate,
                Location = SelectedLocation
            };
            NavigationService.NavigateTo(Dialogs.CreateWeatherRecords, parameter);
        }

        private bool CanExecuteCreateWeatherRecords()
        {
            return SelectedLocation != null;
        }

        public RelayCommand<WeatherRecord> BuildReport
        {
            get
            {
                return _buildReportCommand
                    ?? (_buildReportCommand = new RelayCommand<WeatherRecord>(
                        ExecuteBuildReport,
                        record => record != null));
            }
        }

        private void ExecuteBuildReport(WeatherRecord record)
        {
            var buildTask = Task.Run(() =>
            {
                var b = new FireHazardReportBuilder(_weatherRecordManager);
                var report = b.BuildReport(record);
                return report;
            });
            buildTask.ContinueWith(DispatchError);
            buildTask.ContinueWith(task =>
            {
                if (task.IsFaulted || task.IsCanceled) return;

                DispatcherHelper.CheckBeginInvokeOnUI(() => NavigationService.NavigateTo(Dialogs.ReportBuilder, task.Result));
            });

        }

        public RelayCommand<WeatherRecord> RemoveWeatherRecord
        {
            get
            {
                return _removeWeatherRecordCommand
                    ?? (_removeWeatherRecordCommand = new RelayCommand<WeatherRecord>(
                        ExecuteRemoveWeatherRecord,
                        record => record != null));
            }
        }

        private void ExecuteRemoveWeatherRecord(WeatherRecord record)
        {
            var removeTask = Task.Run(() => _weatherRecordManager.Delete(record));
            removeTask.ContinueWith(task => GetWeatherRecords());
        }

        #endregion
    }
}
{'fraction_non_alphanumeric': 0.0682906516760358, 'fraction_numerical': 0.00027760427510583664, 'mean_word_length': 2.0407258915382993, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '925539', 'n_tokens_mistral': 3395, 'n_tokens_neox': 3176, 'n_words': 648}