<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using StackExchange.Profiling;
using TeamCitySharp;
using TeamCitySharp.DomainEntities;

namespace StackExchange.Opserver.Data
{
    public class BuildStatus
    {
        private static DateTime _lastFetch = DateTime.UtcNow.AddYears(-1);
        private static List<Build> _builds = new List<Build>();
        private static readonly object _fetchLock = new object();
        private static List<Build> Builds
        {
            get
            {
                if (_lastFetch < DateTime.UtcNow.AddSeconds(-Current.Settings.TeamCity.BuildFetchIntervalSeconds))
                {
                    lock (_fetchLock)
                    {
                        if (_lastFetch < DateTime.UtcNow.AddSeconds(-Current.Settings.TeamCity.BuildFetchIntervalSeconds))
                        {
                            using (MiniProfiler.Current.Step("Get Builds since " + _lastFetch.ToString()))
                            {
                                var c = GetClient();
                                // grab all new builds with some overlap
                                var newBuilds = c.Builds.AllSinceDate(_lastFetch.AddSeconds(-10));
                                if (newBuilds != null && newBuilds.Any())
                                {
                                    // merge into the list
                                    _builds.AddRange(newBuilds.Where(b => !_builds.Any(eb => eb.Id == b.Id)));
                                    _builds = _builds.OrderBy(b => b.StartDate).ToList();
                                }
                                _lastFetch = DateTime.UtcNow;
                            }
                        }
                    }
                }
                return _builds;
            }
        }

        public static DateTime LastFetch => _lastFetch;

        public static bool HasCachePrimed =>
            _lastFetch >= DateTime.UtcNow.AddSeconds(-Current.Settings.TeamCity.BuildFetchIntervalSeconds);

        public static List<BuildConfig> Configs
        {
            get
            {
                const string cacheKey = "build-configs";
                var result = Current.LocalCache.Get<List<BuildConfig>>(cacheKey);
                if (result == null)
                {
                    using (MiniProfiler.Current.Step("Get Build Configs"))
                    {
                        result = GetAllBuildConfigs();
                        Current.LocalCache.Set(cacheKey, result, 60*60); // cache for an hour
                    }
                }
                return result;
            }
        }

        public static BuildConfig GetConfig(string buildTypeId) => Configs.FirstOrDefault(c => c.Id == buildTypeId);

        public static List<Build> GetAllBuilds() => Builds;

        public static List<Build> GetBuildsByServer(string server)
        {
            List<string> map;
            if (Current.Settings.TeamCity.ServerMaps.TryGetValue(server.ToLowerInvariant(), out map))
            {
                if(map.Any())
                {
                    return map.SelectMany(GetBuildsById).OrderBy(b => b.StartDate).ToList();
                }
            }
            return new List<Build>();
        }

        public static List<Build> GetBuildsById(string buildTypeId) => Builds.Where(b => b.BuildTypeId == buildTypeId).ToList();

        public static List<BuildConfig> GetAllBuildConfigs()
        {
            var c = GetClient();
            return c.BuildConfigs.All();
        }

        public static List<BuildConfig> GetBuildConfigsByServer(string server)
        {
            List<string> map;
            if (Current.Settings.TeamCity.ServerMaps.TryGetValue(server, out map))
            {
                //var builds = csv.Split(StringSplits.Comma_SemiColon).ToList();
                if(map.Any())
                {
                    return map.Select(GetConfig).Where(c => c != null).OrderBy(b => b.Project).ThenBy(b => b.Name).ToList();
                }
            }
            return new List<BuildConfig>();
        }

        public static List<Project> GetAllProjects()
        {
            var c = GetClient();
            return c.Projects.All();
        }

        public static TeamCityClient GetClient()
        {
            Uri uri;
            var client = Uri.TryCreate(Current.Settings.TeamCity.Url, UriKind.Absolute, out uri)
                ? new TeamCityClient(uri.Host, useSsl: uri.Scheme == Uri.UriSchemeHttps)
                : new TeamCityClient(Current.Settings.TeamCity.Url, useSsl: false);

            client.Connect(Current.Settings.TeamCity.User, Current.Settings.TeamCity.Password);
            return client;
        }
    }
}<commit_msg>Allow TeamcityClient to use custom port<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using StackExchange.Profiling;
using TeamCitySharp;
using TeamCitySharp.DomainEntities;

namespace StackExchange.Opserver.Data
{
    public class BuildStatus
    {
        private static DateTime _lastFetch = DateTime.UtcNow.AddYears(-1);
        private static List<Build> _builds = new List<Build>();
        private static readonly object _fetchLock = new object();
        private static List<Build> Builds
        {
            get
            {
                if (_lastFetch < DateTime.UtcNow.AddSeconds(-Current.Settings.TeamCity.BuildFetchIntervalSeconds))
                {
                    lock (_fetchLock)
                    {
                        if (_lastFetch < DateTime.UtcNow.AddSeconds(-Current.Settings.TeamCity.BuildFetchIntervalSeconds))
                        {
                            using (MiniProfiler.Current.Step("Get Builds since " + _lastFetch.ToString()))
                            {
                                var c = GetClient();
                                // grab all new builds with some overlap
                                var newBuilds = c.Builds.AllSinceDate(_lastFetch.AddSeconds(-10));
                                if (newBuilds != null && newBuilds.Any())
                                {
                                    // merge into the list
                                    _builds.AddRange(newBuilds.Where(b => !_builds.Any(eb => eb.Id == b.Id)));
                                    _builds = _builds.OrderBy(b => b.StartDate).ToList();
                                }
                                _lastFetch = DateTime.UtcNow;
                            }
                        }
                    }
                }
                return _builds;
            }
        }

        public static DateTime LastFetch => _lastFetch;

        public static bool HasCachePrimed =>
            _lastFetch >= DateTime.UtcNow.AddSeconds(-Current.Settings.TeamCity.BuildFetchIntervalSeconds);

        public static List<BuildConfig> Configs
        {
            get
            {
                const string cacheKey = "build-configs";
                var result = Current.LocalCache.Get<List<BuildConfig>>(cacheKey);
                if (result == null)
                {
                    using (MiniProfiler.Current.Step("Get Build Configs"))
                    {
                        result = GetAllBuildConfigs();
                        Current.LocalCache.Set(cacheKey, result, 60*60); // cache for an hour
                    }
                }
                return result;
            }
        }

        public static BuildConfig GetConfig(string buildTypeId) => Configs.FirstOrDefault(c => c.Id == buildTypeId);

        public static List<Build> GetAllBuilds() => Builds;

        public static List<Build> GetBuildsByServer(string server)
        {
            List<string> map;
            if (Current.Settings.TeamCity.ServerMaps.TryGetValue(server.ToLowerInvariant(), out map))
            {
                if(map.Any())
                {
                    return map.SelectMany(GetBuildsById).OrderBy(b => b.StartDate).ToList();
                }
            }
            return new List<Build>();
        }

        public static List<Build> GetBuildsById(string buildTypeId) => Builds.Where(b => b.BuildTypeId == buildTypeId).ToList();

        public static List<BuildConfig> GetAllBuildConfigs()
        {
            var c = GetClient();
            return c.BuildConfigs.All();
        }

        public static List<BuildConfig> GetBuildConfigsByServer(string server)
        {
            List<string> map;
            if (Current.Settings.TeamCity.ServerMaps.TryGetValue(server, out map))
            {
                //var builds = csv.Split(StringSplits.Comma_SemiColon).ToList();
                if(map.Any())
                {
                    return map.Select(GetConfig).Where(c => c != null).OrderBy(b => b.Project).ThenBy(b => b.Name).ToList();
                }
            }
            return new List<BuildConfig>();
        }

        public static List<Project> GetAllProjects()
        {
            var c = GetClient();
            return c.Projects.All();
        }

        public static TeamCityClient GetClient()
        {
            Uri uri;
            var client = Uri.TryCreate(Current.Settings.TeamCity.Url, UriKind.Absolute, out uri)
                ? new TeamCityClient(uri.Host + ":" + uri.Port, useSsl: uri.Scheme == Uri.UriSchemeHttps)
                : new TeamCityClient(Current.Settings.TeamCity.Url, useSsl: false);

            client.Connect(Current.Settings.TeamCity.User, Current.Settings.TeamCity.Password);
            return client;
        }
    }
}
{'fraction_non_alphanumeric': 0.09431029122188828, 'fraction_numerical': 0.0014509275572598197, 'mean_word_length': 1.417940365823102, 'pattern_counts': {'":': 1, '<': 39, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1986888', 'n_tokens_mistral': 2483, 'n_tokens_neox': 2351, 'n_words': 470}