<commit_before>﻿using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace SlackBot.Tfs
{
    /// <summary>
    /// Represents the TFS chat message sink.
    /// </summary>
    public class TfsChatMessageSink : IChatMessageSink
    {
        private static Dictionary<string, string> _colors = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
        {
            { "Bug", "#F35A00" },
            { "Task", "#005AF3" },
            { "User Story", "#5A00F3" },
        };

        private static readonly Regex Pattern = new Regex("(^|\\b)tfs(?<id>[0-9]+)", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);

        private TfsTeamProjectCollection _teamProjectCollection;
        private Guid _teamProjectCollectionGuid;
        private TeamFoundationServer _tfs;
        private WorkItemStore _wis;
        private TswaClientHyperlinkService _tswaHyperlink;

        /// <summary>
        /// Initializes a new instance of the <see cref="TfsChatMessageSink"/> class.
        /// </summary>
        public TfsChatMessageSink()
        {

        }

        /// <summary>
        /// Asynchronously initializes the sink.
        /// </summary>
        /// <param name="name">The configuration name of the sink.</param>
        /// <param name="cancellationToken">A token to monitor for cancellation requests. The default value is <see cref="System.Threading.CancellationToken.None" />.</param>
        /// <returns>
        /// A <see cref="Task" /> that represents the asynchronous initialize operation.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task InitializeAsync(string name, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Delay(0);

            var element = Configuration.TfsConfigurationSection.Current.Sinks[name];
            _teamProjectCollection = new TfsTeamProjectCollection(new Uri(element.ProjectCollection));
            _teamProjectCollectionGuid = _teamProjectCollection.InstanceId;
            _teamProjectCollection.Connect(ConnectOptions.IncludeServices);
            _wis = _teamProjectCollection.GetService<WorkItemStore>();

            _tswaHyperlink = _teamProjectCollection.GetService<TswaClientHyperlinkService>();
        }

        /// <summary>
        /// Asynchronously processes a message.
        /// </summary>
        /// <param name="slack">The slack.</param>
        /// <param name="message">The message.</param>
        /// <param name="cancellationToken">A token to monitor for cancellation requests. The default value is <see cref="System.Threading.CancellationToken.None" />.</param>
        /// <returns>
        /// A <see cref="Task{ChatMessageSinkResult}" /> that represents the asynchronous process operation.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task<ChatMessageSinkResult> ProcessMessageAsync(ISlack slack, Message message, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Delay(0);

            var attachments = new List<Attachment>();
            var matches = Pattern.Matches(message.Text);
            foreach (var id in matches.OfType<Match>().Where(x => x.Success).Select(x => x.Groups["id"]).Where(x => x.Success).Select(x => x.Value))
            {
                WorkItem wi;
                try
                {
                    wi = _wis.GetWorkItem(XmlConvert.ToInt32(id));

                }
                catch (Exception e)
                {
                    continue;
                }

                var link = _tswaHyperlink.GetWorkItemEditorUrl(wi.Id);

                var fields = new List<AttachmentField>()
                    {
                        new AttachmentField("Assigned To", Convert.ToString(wi[CoreField.AssignedTo]), true),<commit_msg>throw for null work item store<commit_after>﻿using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace SlackBot.Tfs
{
    /// <summary>
    /// Represents the TFS chat message sink.
    /// </summary>
    public class TfsChatMessageSink : IChatMessageSink
    {
        private static Dictionary<string, string> _colors = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
        {
            { "Bug", "#F35A00" },
            { "Task", "#005AF3" },
            { "User Story", "#5A00F3" },
        };

        private static readonly Regex Pattern = new Regex("(^|\\b)tfs(?<id>[0-9]+)", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);

        private TfsTeamProjectCollection _teamProjectCollection;
        private Guid _teamProjectCollectionGuid;
        private TeamFoundationServer _tfs;
        private WorkItemStore _wis;
        private TswaClientHyperlinkService _tswaHyperlink;

        /// <summary>
        /// Initializes a new instance of the <see cref="TfsChatMessageSink"/> class.
        /// </summary>
        public TfsChatMessageSink()
        {

        }

        /// <summary>
        /// Asynchronously initializes the sink.
        /// </summary>
        /// <param name="name">The configuration name of the sink.</param>
        /// <param name="cancellationToken">A token to monitor for cancellation requests. The default value is <see cref="System.Threading.CancellationToken.None" />.</param>
        /// <returns>
        /// A <see cref="Task" /> that represents the asynchronous initialize operation.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task InitializeAsync(string name, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Delay(0);

            var element = Configuration.TfsConfigurationSection.Current.Sinks[name];
            _teamProjectCollection = new TfsTeamProjectCollection(new Uri(element.ProjectCollection));
            _teamProjectCollectionGuid = _teamProjectCollection.InstanceId;
            _teamProjectCollection.Connect(ConnectOptions.IncludeServices);
            _wis = _teamProjectCollection.GetService<WorkItemStore>();

            _tswaHyperlink = _teamProjectCollection.GetService<TswaClientHyperlinkService>();
        }

        /// <summary>
        /// Asynchronously processes a message.
        /// </summary>
        /// <param name="slack">The slack.</param>
        /// <param name="message">The message.</param>
        /// <param name="cancellationToken">A token to monitor for cancellation requests. The default value is <see cref="System.Threading.CancellationToken.None" />.</param>
        /// <returns>
        /// A <see cref="Task{ChatMessageSinkResult}" /> that represents the asynchronous process operation.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        public async Task<ChatMessageSinkResult> ProcessMessageAsync(ISlack slack, Message message, CancellationToken cancellationToken = default(CancellationToken))
        {
            await Task.Delay(0);

            if (_wis == null)
            {
                throw new InvalidOperationException("WorkItemStore is null");
            }
            var attachments = new List<Attachment>();
            var matches = Pattern.Matches(message.Text);
            foreach (var id in matches.OfType<Match>().Where(x => x.Success).Select(x => x.Groups["id"]).Where(x => x.Success).Select(x => x.Value))
            {
                WorkItem wi;
                try
                {
                    wi = _wis.GetWorkItem(XmlConvert.ToInt32(id));

                }
                catch (Exception e)
                {
                    continue;
                }

                var link = _tswaHyperlink.GetWorkItemEditorUrl(wi.Id);

                var fields = new List<AttachmentField>()
                    {
                        new AttachmentField("Assigned To", Convert.ToString(wi[CoreField.AssignedTo]), true),
{'fraction_non_alphanumeric': 0.11182770931705632, 'fraction_numerical': 0.004146032477254405, 'mean_word_length': 2.4229404808829327, 'pattern_counts': {'":': 0, '<': 83, '<?xml version=': 0, '>': 91, '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': '5880173', 'n_tokens_mistral': 2218, 'n_tokens_neox': 2178, 'n_words': 500}