<commit_before>﻿namespace tomenglertde.ProjectConfigurationManager.Model
{
    using System;
    using System.Diagnostics.Contracts;

    using TomsToolbox.Desktop;

    public class SolutionContext : ObservableObject, IEquatable<SolutionContext>
    {
        private readonly Solution _solution;
        private readonly SolutionConfiguration _solutionConfiguration;
        private readonly EnvDTE.SolutionContext _ctx;
        private string _configurationName;
        private string _platformName;

        public SolutionContext(Solution solution, SolutionConfiguration solutionConfiguration, EnvDTE.SolutionContext ctx)
        {
            Contract.Requires(solution != null);
            Contract.Requires(solutionConfiguration != null);
            Contract.Requires(ctx != null);

            _solution = solution;
            _solutionConfiguration = solutionConfiguration;
            _ctx = ctx;

            _configurationName = ctx.ConfigurationName;
            _platformName = ctx.PlatformName;

            ProjectName = ctx.ProjectName;
        }

        public string ConfigurationName
        {
            get
            {
                return _configurationName;
            }
            set
            {
                SetProperty(ref _configurationName, value);
            }
        }

        public string PlatformName
        {
            get
            {
                return _platformName;
            }
            set
            {
                SetProperty(ref _platformName, value);
            }
        }

        public bool SetConfiguration(ProjectConfiguration configuration)
        {
            Contract.Requires(configuration != null);

            if ((ConfigurationName == configuration.Configuration) && (PlatformName == configuration.Platform))
                return false;

            _ctx.ConfigurationName = configuration.Configuration + "|" + configuration.Platform;

            ConfigurationName = _ctx.ConfigurationName;
            PlatformName = _ctx.PlatformName;

            return true;
        }

        public string ProjectName
        {
            get;
        }

        public bool ShouldBuild
        {
            get
            {
                return _ctx.ShouldBuild;
            }
            set
            {
                _ctx.ShouldBuild = value;
                OnPropertyChanged();
            }
        }

        public SolutionConfiguration SolutionConfiguration
        {
            get
            {
                Contract.Ensures(Contract.Result<SolutionConfiguration>() != null);
                return _solutionConfiguration;
            }
        }

        #region IEquatable implementation

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {<commit_msg>Avoid AccessViolationException when solution configurations have changed (we don't get a notification, but the com objects are broken)<commit_after>﻿namespace tomenglertde.ProjectConfigurationManager.Model
{
    using System;
    using System.Diagnostics.Contracts;

    using TomsToolbox.Desktop;

    public class SolutionContext : ObservableObject, IEquatable<SolutionContext>
    {
        private readonly Solution _solution;
        private readonly SolutionConfiguration _solutionConfiguration;
        private readonly EnvDTE.SolutionContext _ctx;
        private string _configurationName;
        private string _platformName;

        public SolutionContext(Solution solution, SolutionConfiguration solutionConfiguration, EnvDTE.SolutionContext ctx)
        {
            Contract.Requires(solution != null);
            Contract.Requires(solutionConfiguration != null);
            Contract.Requires(ctx != null);

            _solution = solution;
            _solutionConfiguration = solutionConfiguration;
            _ctx = ctx;

            _configurationName = ctx.ConfigurationName;
            _platformName = ctx.PlatformName;

            ProjectName = ctx.ProjectName;
        }

        public string ConfigurationName
        {
            get
            {
                return _configurationName;
            }
            set
            {
                SetProperty(ref _configurationName, value);
            }
        }

        public string PlatformName
        {
            get
            {
                return _platformName;
            }
            set
            {
                SetProperty(ref _platformName, value);
            }
        }

        public bool SetConfiguration(ProjectConfiguration configuration)
        {
            Contract.Requires(configuration != null);

            if ((ConfigurationName == configuration.Configuration) && (PlatformName == configuration.Platform))
                return false;

            if (!ContextIsValid())
                return false;

            _ctx.ConfigurationName = configuration.Configuration + "|" + configuration.Platform;

            ConfigurationName = _ctx.ConfigurationName;
            PlatformName = _ctx.PlatformName;

            return true;
        }

        public string ProjectName
        {
            get;
        }

        public bool ShouldBuild
        {
            get
            {
                return ContextIsValid() && _ctx.ShouldBuild;
            }
            set
            {
                if (!ContextIsValid())
                    return;

                _ctx.ShouldBuild = value;

                OnPropertyChanged();
            }
        }

        public SolutionConfiguration SolutionConfiguration
        {
            get
            {
                Contract.Ensures(Contract.Result<SolutionConfiguration>() != null);
                return _solutionConfiguration;
            }
        }

        private bool ContextIsValid()
        {
            // Check if the owning collection is valid - accessing other properites would throw an AccessViolationException!
            if (_ctx.Collection?.Count != 0)
                return true;

            // This context is no longer valid, schedule a solution update and return false...
            Dispatcher.BeginInvoke(() => _solution.Update());
            return false;
        }

        #region IEquatable implementation

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode()
        {
{'fraction_non_alphanumeric': 0.06572354848216917, 'fraction_numerical': 0.00014736221632773356, 'mean_word_length': 1.5865091463414633, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 16, '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': '5445879', 'n_tokens_mistral': 1502, 'n_tokens_neox': 1404, 'n_words': 378}