<commit_before>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FakeFreeSwitchSocket.cs" company="<NAME>">
//   (C) <NAME> and contributors. Licensed under the Mozilla Public License.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace NEventSocket.Tests.Fakes
{
    using System;
    using System.Net.Sockets;
    using System.Reactive.Linq;
    using System.Reactive.Subjects;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    using NEventSocket.Sockets;
    using NEventSocket.Tests.TestSupport;
    using NEventSocket.Util;

    /// <summary>
    /// A fake socket client used to simulate the FreeSwitch server on the other end
    /// of an Inbound or Outbound socket.
    /// </summary>
    public class FakeFreeSwitchSocket : ObservableSocket
    {
        private readonly ISubject<string> incomingMessages = new Subject<string>();

        public FakeFreeSwitchSocket(TcpClient client)
            : base(client)
        {
            this.Receiver.SelectMany(x => Encoding.ASCII.GetString(x))
                .AggregateUntil(
                    () => new StringBuilder(), (sb, c) => sb.Append(c), sb => sb.ToString().EndsWith("\n\n"))
                .Select(x => x.ToString().Remove(x.Length - 2, 2))
                .Subscribe(
                    x => incomingMessages.OnNext(x),
                    ex => incomingMessages.OnError(ex),
                    () => incomingMessages.OnCompleted());
        }

        public FakeFreeSwitchSocket(int port)
            : this(new TcpClient("127.0.0.1", port))
        {
        }

        public IObservable<string> MessagesReceived
        {
            get
            {
                return incomingMessages;
            }
        }

        public Task Send(string message)
        {
            return this.SendAsync(message + "\n\n", CancellationToken.None);
        }

        public Task SendChannelDataEvent()
        {
            var msg = TestMessages.ConnectEvent.Replace("\r\n", "\n") + "\n\n";
            return this.SendAsync(msg, CancellationToken.None);
        }

        public Task SendCommandReplyOk()
        {
            return this.SendAsync("Content-Type: command/reply\nReply-Text: +OK\n\n", CancellationToken.None);
        }

        public Task SendCommandReplyError(string error)
        {
            return this.SendAsync("Content-Type: command/reply\nReply-Text: -ERR {0}\n\n".Fmt(error), CancellationToken.None);
        }

        public Task SendApiResponseOk()
        {<commit_msg>Add test helpers<commit_after>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FakeFreeSwitchSocket.cs" company="<NAME>">
//   (C) <NAME> and contributors. Licensed under the Mozilla Public License.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace NEventSocket.Tests.Fakes
{
    using System;
    using System.Net.Sockets;
    using System.Reactive.Linq;
    using System.Reactive.Subjects;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    using NEventSocket.Sockets;
    using NEventSocket.Tests.TestSupport;
    using NEventSocket.Util;

    /// <summary>
    /// A fake socket client used to simulate the FreeSwitch server on the other end
    /// of an Inbound or Outbound socket.
    /// </summary>
    public class FakeFreeSwitchSocket : ObservableSocket
    {
        private readonly ISubject<string> incomingMessages = new Subject<string>();

        public FakeFreeSwitchSocket(TcpClient client)
            : base(client)
        {
            this.Receiver.SelectMany(x => Encoding.ASCII.GetString(x))
                .AggregateUntil(
                    () => new StringBuilder(), (sb, c) => sb.Append(c), sb => sb.ToString().EndsWith("\n\n"))
                .Select(x => x.ToString().Remove(x.Length - 2, 2))
                .Subscribe(
                    x => incomingMessages.OnNext(x),
                    ex => incomingMessages.OnError(ex),
                    () => incomingMessages.OnCompleted());
        }

        public FakeFreeSwitchSocket(int port)
            : this(new TcpClient("127.0.0.1", port))
        {
        }

        public IObservable<string> MessagesReceived
        {
            get
            {
                return incomingMessages;
            }
        }

        public Task Send(string message)
        {
            return this.SendAsync(message + "\n\n", CancellationToken.None);
        }

        public Task SendChannelDataEvent()
        {
            var msg = TestMessages.ConnectEvent.Replace("\r\n", "\n") + "\n\n";
            return this.SendAsync(msg, CancellationToken.None);
        }

        public Task SendDisconnectNotice()
        {
            return this.SendAsync("Content-Type: text/disconnect-notice\nContent-Length: 67\n\nDisconnected, goodbye.\nSee you at ClueCon! http://www.cluecon.com/\n", CancellationToken.None);
        }

        public Task SendCommandReplyOk(string message = null)
        {
            return this.SendAsync("Content-Type: command/reply\nReply-Text: +OK {0}\n\n".Fmt(message), CancellationToken.None);
        }

        public Task SendCommandReplyError(string error)
        {
            return this.SendAsync("Content-Type: command/reply\nReply-Text: -ERR {0}\n\n".Fmt(error), CancellationToken.None);
        }

        public Task SendApiResponseOk()
        {
{'fraction_non_alphanumeric': 0.18926010145181038, 'fraction_numerical': 0.0036732552037782055, 'mean_word_length': 1.5908473040326234, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 2, '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': '3103846', 'n_tokens_mistral': 1469, 'n_tokens_neox': 1443, 'n_words': 308}