<commit_before>﻿namespace tomenglertde.ProjectConfigurationManager.Model
{
    using System;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Diagnostics.Contracts;
    using System.IO;
    using System.Linq;

    using TomsToolbox.Core;
    using TomsToolbox.Desktop;
    using TomsToolbox.ObservableCollections;

    public class Project : ObservableObject, IEquatable<Project>
    {
        private readonly EnvDTE.Project _project;

        private readonly Solution _solution;
        private readonly string _uniqueName;
        private readonly string _name;
        private readonly string _fullName;

        private readonly ObservableCollection<ProjectConfiguration> _internalSpecificProjectConfigurations = new ObservableCollection<ProjectConfiguration>();
        private readonly ReadOnlyObservableCollection<ProjectConfiguration> _specificProjectConfigurations;
        private readonly IObservableCollection<SolutionContext> _solutionContexts;
        private readonly ProjectConfiguration _defaultProjectConfiguration;

        private ProjectFile _projectFile;

        internal Project(Solution solution, EnvDTE.Project project)
        {
            Contract.Requires(solution != null);
            Contract.Requires(project != null);
            Contract.Requires(!string.IsNullOrEmpty(project.FullName));
            Contract.Requires(!string.IsNullOrEmpty(project.UniqueName));

            _solution = solution;
            _project = project;
            _uniqueName = _project.UniqueName;
            _name = _project.Name;
            _fullName = _project.FullName;

            _projectFile = new ProjectFile(solution, this);

            _defaultProjectConfiguration = new ProjectConfiguration(this, null, null);
            _specificProjectConfigurations = new ReadOnlyObservableCollection<ProjectConfiguration>(_internalSpecificProjectConfigurations);
            _solutionContexts = _solution.SolutionContexts.ObservableWhere(context => context.ProjectName == _uniqueName);

            Update();
        }

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

        public string Name
        {
            get
            {
                Contract.Ensures(Contract.Result<string>() != null);
                return _name;
            }
        }

        public string UniqueName
        {
            get
            {
                Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
                return _uniqueName;
            }
        }

        public string RelativePath
        {
            get
            {
                Contract.Ensures(Contract.Result<string>() != null);
                return Path.GetDirectoryName(UniqueName);
            }
        }

        public string SortKey
        {
            get
            {
                Contract.Ensures(Contract.Result<string>() != null);
                return _name + " (" + RelativePath + ")";
            }
        }

        public string FullName
        {
            get
            {
                Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
                return _fullName;
            }
        }

        public string[] ProjectTypeGuids
        {
            get
            {
                Contract.Ensures(Contract.Result<string[]>() != null);
                return RetrieveProjectTypeGuids();
            }
        }

        public IObservableCollection<SolutionContext> SolutionContexts
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservableCollection<SolutionContext>>() != null);
                return _solutionContexts;
            }
        }

        public ReadOnlyObservableCollection<ProjectConfiguration> SpecificProjectConfigurations
        {
            get
            {
                Contract.Ensures(Contract.Result<ReadOnlyObservableCollection<ProjectConfiguration>>() != null);
                return _specificProjectConfigurations;
            }
        }

        public ProjectConfiguration DefaultProjectConfiguration
        {
            get
            {
                Contract.Ensures(Contract.Result<ProjectConfiguration>() != null);
                return _defaultProjectConfiguration;
            }
        }

        public bool IsSaving => _projectFile.IsSaving;

        public DateTime FileTime => _projectFile.FileTime;

        internal bool IsSaved
        {
            get
            {
                try
                {
                    return _project.Saved;
                }
                catch
                {
                    // project is currently unloaded...
                    return true;
                }
            }
        }

        public bool CanEdit()
        {
            return IsSaved && _projectFile.CanEdit();
        }

        public void Reload()
        {
            _projectFile = new ProjectFile(_solution, this);

            Update();
        }

        internal void Update()
        {
            var configurationManager = _project.ConfigurationManager;

            var projectConfigurations = Enumerable.Empty<ProjectConfiguration>();

            if (configurationManager != null)
            {
                var configurationNames = ((IEnumerable)configurationManager.ConfigurationRowNames)?.OfType<string>();
                var platformNames = ((IEnumerable)configurationManager.PlatformNames)?.OfType<string>();

                if ((configurationNames != null) && (platformNames != null))
                {
                    projectConfigurations = configurationNames
                        .SelectMany(configuration => platformNames.Select(platform => new ProjectConfiguration(this, configuration, platform)));
                }
            }

            _internalSpecificProjectConfigurations.SynchronizeWith(projectConfigurations.ToArray());

            _defaultProjectConfiguration.SetProjectFile(_projectFile);

            _internalSpecificProjectConfigurations.ForEach(config => config.SetProjectFile(_projectFile));

        }

        internal IProjectProperty CreateProperty(string propertyName, string configuration, string platform)
        {<commit_msg>Hide configurations that have no corresponding project file entry.<commit_after>﻿namespace tomenglertde.ProjectConfigurationManager.Model
{
    using System;
    using System.Collections;
    using System.Collections.ObjectModel;
    using System.Diagnostics.CodeAnalysis;
    using System.Diagnostics.Contracts;
    using System.IO;
    using System.Linq;

    using TomsToolbox.Core;
    using TomsToolbox.Desktop;
    using TomsToolbox.ObservableCollections;

    public class Project : ObservableObject, IEquatable<Project>
    {
        private readonly EnvDTE.Project _project;

        private readonly Solution _solution;
        private readonly string _uniqueName;
        private readonly string _name;
        private readonly string _fullName;

        private readonly ObservableCollection<ProjectConfiguration> _internalSpecificProjectConfigurations = new ObservableCollection<ProjectConfiguration>();
        private readonly ReadOnlyObservableCollection<ProjectConfiguration> _specificProjectConfigurations;
        private readonly IObservableCollection<SolutionContext> _solutionContexts;
        private readonly ProjectConfiguration _defaultProjectConfiguration;

        private ProjectFile _projectFile;

        internal Project(Solution solution, EnvDTE.Project project)
        {
            Contract.Requires(solution != null);
            Contract.Requires(project != null);
            Contract.Requires(!string.IsNullOrEmpty(project.FullName));
            Contract.Requires(!string.IsNullOrEmpty(project.UniqueName));

            _solution = solution;
            _project = project;
            _uniqueName = _project.UniqueName;
            _name = _project.Name;
            _fullName = _project.FullName;

            _projectFile = new ProjectFile(solution, this);

            _defaultProjectConfiguration = new ProjectConfiguration(this, null, null);
            _specificProjectConfigurations = new ReadOnlyObservableCollection<ProjectConfiguration>(_internalSpecificProjectConfigurations);
            _solutionContexts = _solution.SolutionContexts.ObservableWhere(context => context.ProjectName == _uniqueName);

            Update();
        }

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

        public string Name
        {
            get
            {
                Contract.Ensures(Contract.Result<string>() != null);
                return _name;
            }
        }

        public string UniqueName
        {
            get
            {
                Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
                return _uniqueName;
            }
        }

        public string RelativePath
        {
            get
            {
                Contract.Ensures(Contract.Result<string>() != null);
                return Path.GetDirectoryName(UniqueName);
            }
        }

        public string SortKey
        {
            get
            {
                Contract.Ensures(Contract.Result<string>() != null);
                return _name + " (" + RelativePath + ")";
            }
        }

        public string FullName
        {
            get
            {
                Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>()));
                return _fullName;
            }
        }

        public string[] ProjectTypeGuids
        {
            get
            {
                Contract.Ensures(Contract.Result<string[]>() != null);
                return RetrieveProjectTypeGuids();
            }
        }

        public IObservableCollection<SolutionContext> SolutionContexts
        {
            get
            {
                Contract.Ensures(Contract.Result<IObservableCollection<SolutionContext>>() != null);
                return _solutionContexts;
            }
        }

        public ReadOnlyObservableCollection<ProjectConfiguration> SpecificProjectConfigurations
        {
            get
            {
                Contract.Ensures(Contract.Result<ReadOnlyObservableCollection<ProjectConfiguration>>() != null);
                return _specificProjectConfigurations;
            }
        }

        public ProjectConfiguration DefaultProjectConfiguration
        {
            get
            {
                Contract.Ensures(Contract.Result<ProjectConfiguration>() != null);
                return _defaultProjectConfiguration;
            }
        }

        public bool IsSaving => _projectFile.IsSaving;

        public DateTime FileTime => _projectFile.FileTime;

        internal bool IsSaved
        {
            get
            {
                try
                {
                    return _project.Saved;
                }
                catch
                {
                    // project is currently unloaded...
                    return true;
                }
            }
        }

        public bool CanEdit()
        {
            return IsSaved && _projectFile.CanEdit();
        }

        public void Reload()
        {
            _projectFile = new ProjectFile(_solution, this);

            Update();
        }

        internal void Update()
        {
            var configurationManager = _project.ConfigurationManager;

            var projectConfigurations = Enumerable.Empty<ProjectConfiguration>();

            if (configurationManager != null)
            {
                var configurationNames = ((IEnumerable)configurationManager.ConfigurationRowNames)?.OfType<string>();
                var platformNames = ((IEnumerable)configurationManager.PlatformNames)?.OfType<string>();

                if ((configurationNames != null) && (platformNames != null))
                {
                    projectConfigurations = configurationNames
                        .SelectMany(configuration => platformNames
                            .Where(platform => _projectFile.HasConfiguration(configuration, platform))
                            .Select(platform => new ProjectConfiguration(this, configuration, platform)));
                }
            }

            _internalSpecificProjectConfigurations.SynchronizeWith(projectConfigurations.ToArray());

            _defaultProjectConfiguration.SetProjectFile(_projectFile);

            _internalSpecificProjectConfigurations.ForEach(config => config.SetProjectFile(_projectFile));

        }

        internal IProjectProperty CreateProperty(string propertyName, string configuration, string platform)
        {
{'fraction_non_alphanumeric': 0.07325109187035476, 'fraction_numerical': 0.0, 'mean_word_length': 1.7954594131505677, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 62, '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': '3620972', 'n_tokens_mistral': 2959, 'n_tokens_neox': 2784, 'n_words': 540}