<commit_before>﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace PoshGit2
{
    public class NamedPipeRepoCache : IRepositoryCache
    {
        private readonly JsonSerializer _serializer;

        public NamedPipeRepoCache()
        {
            _serializer = JsonSerializer.Create();
        }

        private async Task<T> SendReceiveCommandAsync<T>(Func<StreamReader, StreamWriter, Task<T>> func)
        {
            using (var pipe = new NamedPipeClientStream(NamedPipeRepoServer.ServerName, NamedPipeRepoServer.PipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
            {
                pipe.Connect();

                using (var writer = new NonClosingStreamWriter(pipe) { AutoFlush = true })
                using (var reader = new NonClosingStreamReader(pipe))
                {
                    return await func(reader, writer);
                }
            }
        }

        public Task<IRepositoryStatus> FindRepoAsync(ICurrentWorkingDirectory cwd, CancellationToken cancellationToken)
        {
            return SendReceiveCommandAsync(async (reader, writer) =>
            {
                await writer.WriteAsync(NamedPipeCommand.FindRepo);

                var response = await reader.ReadCommandAsync();

                if (response != NamedPipeCommand.Ready)
                {
                    return null;
                }

                await writer.WriteLineAsync(cwd.CWD);

                using (var jsonReader = new JsonTextReader(reader))
                {
                    return _serializer
                        .Deserialize<ReadWriteRepositoryStatus>(jsonReader) as IRepositoryStatus;
                }
            });
        }

        public Task<IEnumerable<IRepositoryStatus>> GetAllReposAsync(CancellationToken cancellationToken)
        {
            return SendReceiveCommandAsync(async (reader, writer) =>
            {
                await writer.WriteAsync(NamedPipeCommand.GetAllRepos);

                var response = await reader.ReadCommandAsync();

                if (response != NamedPipeCommand.Ready)
                {
                    return null;
                }

                using (var jsonReader = new JsonTextReader(reader))
                {
                    return _serializer
                        .Deserialize<IEnumerable<ReadWriteRepositoryStatus>>(jsonReader)
                        .Cast<IRepositoryStatus>();
                }
            });
        }

        public Task<bool> RemoveRepoAsync(string path, CancellationToken cancellationToken)
        {
            return SendReceiveCommandAsync(async (reader, writer) =>
            {
                await writer.WriteAsync(NamedPipeCommand.RemoveRepo);

                var response = await reader.ReadCommandAsync();

                if (response != NamedPipeCommand.Ready)
                {
                    return false;
                }

                await writer.WriteLineAsync(path);

                var result = await reader.ReadCommandAsync();

                return result == NamedPipeCommand.Success;
            });
        }
    }
}<commit_msg>Refactor redundant code in NamedPipeRepoCache<commit_after>﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace PoshGit2
{
    public class NamedPipeRepoCache : IRepositoryCache
    {
        private readonly JsonSerializer _serializer;

        public NamedPipeRepoCache()
        {
            _serializer = JsonSerializer.Create();
        }

        public Task<IRepositoryStatus> FindRepoAsync(ICurrentWorkingDirectory cwd, CancellationToken cancellationToken)
        {
            return SendReceiveCommandAsync(async (reader, writer) =>
            {
                await writer.WriteLineAsync(cwd.CWD);

                using (var jsonReader = new JsonTextReader(reader))
                {
                    return _serializer
                        .Deserialize<ReadWriteRepositoryStatus>(jsonReader) as IRepositoryStatus;
                }
            }, NamedPipeCommand.FindRepo);
        }

        public Task<IEnumerable<IRepositoryStatus>> GetAllReposAsync(CancellationToken cancellationToken)
        {
            return SendReceiveCommandAsync((reader, writer) =>
            {
                using (var jsonReader = new JsonTextReader(reader))
                {
                    var result = _serializer
                        .Deserialize<IEnumerable<ReadWriteRepositoryStatus>>(jsonReader)
                        .Cast<IRepositoryStatus>();

                    return Task.FromResult(result);
                }
            }, NamedPipeCommand.GetAllRepos);
        }

        public Task<bool> RemoveRepoAsync(string path, CancellationToken cancellationToken)
        {
            return SendReceiveCommandAsync(async (reader, writer) =>
            {
                await writer.WriteLineAsync(path);

                var result = await reader.ReadCommandAsync();

                return result == NamedPipeCommand.Success;
            }, NamedPipeCommand.RemoveRepo);
        }

        private async Task<T> SendReceiveCommandAsync<T>(Func<StreamReader, StreamWriter, Task<T>> func, NamedPipeCommand command)
        {
            using (var pipe = new NamedPipeClientStream(NamedPipeRepoServer.ServerName, NamedPipeRepoServer.PipeName, PipeDirection.InOut, PipeOptions.Asynchronous))
            {
                pipe.Connect();

                using (var writer = new NonClosingStreamWriter(pipe) { AutoFlush = true })
                using (var reader = new NonClosingStreamReader(pipe))
                {
                    await writer.WriteAsync(command);

                    var response = await reader.ReadCommandAsync();

                    if (response != NamedPipeCommand.Ready)
                    {
                        return default(T);
                    }

                    return await func(reader, writer);
                }
            }
        }
    }
}
{'fraction_non_alphanumeric': 0.07252678987420406, 'fraction_numerical': 0.00031060723714862557, 'mean_word_length': 1.6168224299065421, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 33, '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': '399699', 'n_tokens_mistral': 1596, 'n_tokens_neox': 1490, 'n_words': 295}