<commit_before>﻿using SIM.Extensions;

namespace SIM.Instances
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using Microsoft.Web.Administration;
  using SIM.Adapters.WebServer;
  using Sitecore.Diagnostics.Base;
  using JetBrains.Annotations;
  using Sitecore.Diagnostics.Base.Extensions.EnumerableExtensions;
  using Sitecore.Diagnostics.Logging;
  using SIM.SitecoreEnvironments;

  #region

  #endregion

  public class InstanceManager
  {
    #region Fields

    private IDictionary<string, Instance> _CachedInstances;
    private IEnumerable<Instance> _Instances;
    private string _InstancesFolder;

    #endregion

    #region Properties

    #region Delegates

    public event EventHandler InstancesListUpdated;

    #endregion

    #region Public properties

    [CanBeNull]
    public IEnumerable<Instance> Instances
    {
      get
      {
        return _Instances;
      }

      private set
      {
        _Instances = value;
        OnInstancesListUpdated();
      }
    }

    [CanBeNull]
    public IDictionary<string, Instance> PartiallyCachedInstances
    {
      get
      {
        // I believe that this check is redundant because the this list is filled before Instances list is actually filled.
        if (_CachedInstances != null)
        {
          return _CachedInstances;
        }

        if (Instances == null)
        {
          return null;
        }

        _CachedInstances = new Dictionary<string, Instance>();
        Instances.ForEach(x => { _CachedInstances.Add(x.Name, new PartiallyCachedInstance((int)x.ID)); });

        return _CachedInstances;
      }

      private set
      {
        if (_CachedInstances != null)
        {
          foreach (var cachedInstance in _CachedInstances.Values.OfType<IDisposable>())
          {
            if (cachedInstance != null)
            {
              cachedInstance.Dispose();
            }
          }
        }

        _CachedInstances = value;
      }
    }

    public static InstanceManager Default { get; } = new InstanceManager();

    #endregion

    #endregion

    #region Public Methods

    #region Public methods

    [CanBeNull]
    public Instance GetInstance([NotNull] string name)
    {
      Assert.ArgumentNotNull(name, nameof(name));
      Log.Debug($"InstanceManager:GetInstance('{name}')");

      if (Instances == null)
      {
        Initialize();
      }

      if (Instances == null)
      {
        return null;
      }

      return PartiallyCachedInstances?[name];
    }

    public void Initialize([CanBeNull] string defaultRootFolder = null)
    {
      SitecoreEnvironmentHelper.RefreshEnvironments();

      List<Instance> instances = new List<Instance>();

      instances.AddRange(GetIISInstances());

      instances.AddRange(GetContainerizedInstances());

      Dictionary<string, Instance> partiallyCachedInstances = instances.ToDictionary(i => i.Name);

      PartiallyCachedInstances = partiallyCachedInstances;

      Instances = instances;
    }

    private IEnumerable<Instance> GetContainerizedInstances()
    {
      List<SitecoreEnvironment> environments =
        SitecoreEnvironmentHelper.SitecoreEnvironments.
          Where(e => e.EnvType == SitecoreEnvironment.EnvironmentType.Container).ToList();

      List<Instance> instances = environments.SelectMany(e => e.Members).Select(m => MemberToInstance(m)).ToList();

      return instances;
    }

    private Instance MemberToInstance(SitecoreEnvironmentMember member)
    {
      Instance instance = new ContainerizedInstance(member.Name);

      return instance;
    }

    private IEnumerable<Instance> GetIISInstances([CanBeNull] string defaultRootFolder = null)
    {
      using (WebServerManager.WebServerContext context = WebServerManager.CreateContext())
      {
        ProfileSection.Argument("defaultRootFolder", defaultRootFolder);

        IEnumerable<Site> sites = GetOperableSites(context, defaultRootFolder);

        return GetPartiallyCachedInstances(sites);
      }

      return GetInstances();
    }

    public void InitializeWithSoftListRefresh([CanBeNull] string defaultRootFolder = null)
    {
      SitecoreEnvironmentHelper.RefreshEnvironments();

      using (new ProfileSection("Initialize with soft list refresh"))
      {
        // Add check that this isn't an initial initialization
        if (Instances == null)
        {
          Initialize(defaultRootFolder);
        }

        using (WebServerManager.WebServerContext context = WebServerManager.CreateContext())
        {
          IEnumerable<Site> sites = GetOperableSites(context, defaultRootFolder);

          // The trick is in reused PartiallyCachedInstances. We use site ID as identificator that cached instance may be reused. If we can't fetch instance from cache, we create new.
          PartiallyCachedInstances = sites.Select(site =>
              PartiallyCachedInstances?.Values.FirstOrDefault(cachedInst => cachedInst.ID == site.Id) ??<commit_msg>Remove unreachable code in the InstanceManager<commit_after>﻿using SIM.Extensions;

namespace SIM.Instances
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using Microsoft.Web.Administration;
  using SIM.Adapters.WebServer;
  using Sitecore.Diagnostics.Base;
  using JetBrains.Annotations;
  using Sitecore.Diagnostics.Base.Extensions.EnumerableExtensions;
  using Sitecore.Diagnostics.Logging;
  using SIM.SitecoreEnvironments;

  #region

  #endregion

  public class InstanceManager
  {
    #region Fields

    private IDictionary<string, Instance> _CachedInstances;
    private IEnumerable<Instance> _Instances;
    private string _InstancesFolder;

    #endregion

    #region Properties

    #region Delegates

    public event EventHandler InstancesListUpdated;

    #endregion

    #region Public properties

    [CanBeNull]
    public IEnumerable<Instance> Instances
    {
      get
      {
        return _Instances;
      }

      private set
      {
        _Instances = value;
        OnInstancesListUpdated();
      }
    }

    [CanBeNull]
    public IDictionary<string, Instance> PartiallyCachedInstances
    {
      get
      {
        // I believe that this check is redundant because the this list is filled before Instances list is actually filled.
        if (_CachedInstances != null)
        {
          return _CachedInstances;
        }

        if (Instances == null)
        {
          return null;
        }

        _CachedInstances = new Dictionary<string, Instance>();
        Instances.ForEach(x => { _CachedInstances.Add(x.Name, new PartiallyCachedInstance((int)x.ID)); });

        return _CachedInstances;
      }

      private set
      {
        if (_CachedInstances != null)
        {
          foreach (var cachedInstance in _CachedInstances.Values.OfType<IDisposable>())
          {
            if (cachedInstance != null)
            {
              cachedInstance.Dispose();
            }
          }
        }

        _CachedInstances = value;
      }
    }

    public static InstanceManager Default { get; } = new InstanceManager();

    #endregion

    #endregion

    #region Public Methods

    #region Public methods

    [CanBeNull]
    public Instance GetInstance([NotNull] string name)
    {
      Assert.ArgumentNotNull(name, nameof(name));
      Log.Debug($"InstanceManager:GetInstance('{name}')");

      if (Instances == null)
      {
        Initialize();
      }

      if (Instances == null)
      {
        return null;
      }

      return PartiallyCachedInstances?[name];
    }

    public void Initialize([CanBeNull] string defaultRootFolder = null)
    {
      SitecoreEnvironmentHelper.RefreshEnvironments();

      List<Instance> instances = new List<Instance>();

      instances.AddRange(GetIISInstances());

      instances.AddRange(GetContainerizedInstances());

      Dictionary<string, Instance> partiallyCachedInstances = instances.ToDictionary(i => i.Name);

      PartiallyCachedInstances = partiallyCachedInstances;

      Instances = instances;
    }

    private IEnumerable<Instance> GetContainerizedInstances()
    {
      List<SitecoreEnvironment> environments =
        SitecoreEnvironmentHelper.SitecoreEnvironments.
          Where(e => e.EnvType == SitecoreEnvironment.EnvironmentType.Container).ToList();

      List<Instance> instances = environments.SelectMany(e => e.Members).Select(m => MemberToInstance(m)).ToList();

      return instances;
    }

    private Instance MemberToInstance(SitecoreEnvironmentMember member)
    {
      Instance instance = new ContainerizedInstance(member.Name);

      return instance;
    }

    private IEnumerable<Instance> GetIISInstances([CanBeNull] string defaultRootFolder = null)
    {
      using (WebServerManager.WebServerContext context = WebServerManager.CreateContext())
      {
        ProfileSection.Argument("defaultRootFolder", defaultRootFolder);

        IEnumerable<Site> sites = GetOperableSites(context, defaultRootFolder);

        return GetPartiallyCachedInstances(sites);
      }
    }

    public void InitializeWithSoftListRefresh([CanBeNull] string defaultRootFolder = null)
    {
      SitecoreEnvironmentHelper.RefreshEnvironments();

      using (new ProfileSection("Initialize with soft list refresh"))
      {
        // Add check that this isn't an initial initialization
        if (Instances == null)
        {
          Initialize(defaultRootFolder);
        }

        using (WebServerManager.WebServerContext context = WebServerManager.CreateContext())
        {
          IEnumerable<Site> sites = GetOperableSites(context, defaultRootFolder);

          // The trick is in reused PartiallyCachedInstances. We use site ID as identificator that cached instance may be reused. If we can't fetch instance from cache, we create new.
          PartiallyCachedInstances = sites.Select(site =>
              PartiallyCachedInstances?.Values.FirstOrDefault(cachedInst => cachedInst.ID == site.Id) ??
{'fraction_non_alphanumeric': 0.08392660182492731, 'fraction_numerical': 0.0, 'mean_word_length': 2.7680392897619948, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 47, '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': '7133248', 'n_tokens_mistral': 2689, 'n_tokens_neox': 2606, 'n_words': 597}