using System.Globalization;
using System.Threading;

namespace Umbraco.Core
{
    static class ThreadExtensions
    {
        public static void SanitizeThreadCulture(this Thread thread)
        {
            // get the current culture
            var currentCulture = CultureInfo.CurrentCulture;

            // at the top of any culture should be the invariant culture - find it
            // doing an .Equals comparison ensure that we *will* find it and not loop
            // endlessly
            var invariantCulture = currentCulture;
            while (invariantCulture.Equals(CultureInfo.InvariantCulture) == false)
                invariantCulture = invariantCulture.Parent;

            // now that invariant culture should be the same object as CultureInfo.InvariantCulture
            // yet for some reasons, sometimes it is not - and this breaks anything that loops on
            // culture.Parent until a reference equality to CultureInfo.InvariantCulture. See, for
            // example, the following code in PerformanceCounterLib.IsCustomCategory:
            //
            // CultureInfo culture = CultureInfo.CurrentCulture;
            // while (culture != CultureInfo.InvariantCulture)
            // {
            //     library = GetPerformanceCounterLib(machine, culture);
            //     if (library.IsCustomCategory(category))
            //         return true;
            //     culture = culture.Parent;
            // }
            //
            // The reference comparisons never succeeds, hence the loop never ends, and the
            // application hangs.
            //
            // granted, that comparison should probably be a .Equals comparison, but who knows
            // how many times the framework assumes that it can do a reference comparison? So,
            // better fix the cultures.

            if (ReferenceEquals(invariantCulture, CultureInfo.InvariantCulture))
                return;

            // if we do not have equality, fix cultures by replacing them with a culture with
            // the same name, but obtained here and now, with a proper invariant top culture

            thread.CurrentCulture = CultureInfo.GetCultureInfo(thread.CurrentCulture.Name);
            thread.CurrentUICulture = CultureInfo.GetCultureInfo(thread.CurrentUICulture.Name);
        }
    }
}
