<commit_before>﻿using Handyman.Tools.Outdated.Model;
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Text;

namespace Handyman.Tools.Outdated.Analyze
{
    public class MarkdownFileWriter : IFileWriter
    {
        private readonly IFileSystem _fileSystem;

        public MarkdownFileWriter(IFileSystem fileSystem)
        {
            _fileSystem = fileSystem;
        }

        public bool CanHandle(string extension)
        {
            return extension == ".md";
        }

        public void Write(string path, IEnumerable<Project> projects)
        {
            var builder = new StringBuilder();

            projects = projects.ToList();

            var errors = projects.Where(x => x.Errors.Any()).ToList();
            var outdated = projects.Where(x => x.TargetFrameworks.Any()).ToList();
            var upToDate = projects.Where(x => !errors.Contains(x) && !outdated.Contains(x)).ToList();

            if (!projects.Any())
            {
                builder.AppendLine("No projects found");
            }
            else
            {
                builder.AppendLine("# Summary");

                if (errors.Any())
                {
                    builder.AppendLine($"* {errors.Count} projects failed");
                }

                builder.AppendLine($"* {outdated.Count} projects has outdated dependencies");
                builder.AppendLine($"* {upToDate.Count} projects are up to date");
                builder.AppendLine();

                if (errors.Any())
                {
                    builder.AppendLine("# Failed");

                    foreach (var project in errors)
                    {
                        AppendProjectInfo(builder, project);

                        foreach (var error in project.Errors)
                        {
                            builder.AppendLine($"### {error.Stage}");
                            builder.AppendLine(error.Message);
                        }
                    }

                    builder.AppendLine();
                }

                if (outdated.Any())
                {
                    builder.AppendLine("# Outdated");

                    foreach (var project in outdated)
                    {
                        AppendProjectInfo(builder, project);

                        foreach (var framework in project.TargetFrameworks)
                        {
                            builder.AppendLine($"### {framework.Name}");
                            builder.AppendLine("| Package | Current | Major | Minor | Patch | Transitive |");
                            builder.AppendLine("| - | - | - | - | - | - |");

                            foreach (var package in framework.Packages)
                            {
                                builder
                                    .Append($"| {package.Name} |")
                                    .Append($" {package.CurrentVersion} |")
                                    .Append($" {package.AvailableVersions.GetValueOrDefault(Severity.Major)} |")
                                    .Append($" {package.AvailableVersions.GetValueOrDefault(Severity.Minor)} |")
                                    .Append($" {package.AvailableVersions.GetValueOrDefault(Severity.Patch)} |")
                                    .Append($" {package.IsTransitive.ToString().ToLowerInvariant()} |")
                                    .AppendLine();
                            }
                        }
                    }

                    builder.AppendLine();
                }

                if (upToDate.Any())
                {
                    builder.AppendLine("# Up to date");

                    foreach (var project in outdated)
                    {
                        AppendProjectInfo(builder, project);
                    }

                    builder.AppendLine();
                }
            }

            builder.AppendLine("***");
            builder.AppendLine($"_{AppInfo.AppName} {DateTimeOffset.UtcNow:yyyy-MM-dd HH:mm UTC}_");

            var directory = _fileSystem.Path.GetDirectoryName(path);
            if (!_fileSystem.Directory.Exists(directory))
                _fileSystem.Directory.CreateDirectory(directory);

            _fileSystem.File.WriteAllText(path, builder.ToString(), Encoding.UTF8);
        }

        private static void AppendProjectInfo(StringBuilder builder, Project project)
        {<commit_msg>fixed up to date projects listing in markdown file writer<commit_after>﻿using Handyman.Tools.Outdated.Model;
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Text;

namespace Handyman.Tools.Outdated.Analyze
{
    public class MarkdownFileWriter : IFileWriter
    {
        private readonly IFileSystem _fileSystem;

        public MarkdownFileWriter(IFileSystem fileSystem)
        {
            _fileSystem = fileSystem;
        }

        public bool CanHandle(string extension)
        {
            return extension == ".md";
        }

        public void Write(string path, IEnumerable<Project> projects)
        {
            var builder = new StringBuilder();

            projects = projects.ToList();

            var errors = projects.Where(x => x.Errors.Any()).ToList();
            var outdated = projects.Where(x => x.TargetFrameworks.Any()).ToList();
            var upToDate = projects.Where(x => !errors.Contains(x) && !outdated.Contains(x)).ToList();

            if (!projects.Any())
            {
                builder.AppendLine("No projects found");
            }
            else
            {
                builder.AppendLine("# Summary");

                if (errors.Any())
                {
                    builder.AppendLine($"* {errors.Count} projects failed");
                }

                builder.AppendLine($"* {outdated.Count} projects has outdated dependencies");
                builder.AppendLine($"* {upToDate.Count} projects are up to date");
                builder.AppendLine();

                if (errors.Any())
                {
                    builder.AppendLine("# Failed");

                    foreach (var project in errors)
                    {
                        AppendProjectInfo(builder, project);

                        foreach (var error in project.Errors)
                        {
                            builder.AppendLine($"### {error.Stage}");
                            builder.AppendLine(error.Message);
                        }
                    }

                    builder.AppendLine();
                }

                if (outdated.Any())
                {
                    builder.AppendLine("# Outdated");

                    foreach (var project in outdated)
                    {
                        AppendProjectInfo(builder, project);

                        foreach (var framework in project.TargetFrameworks)
                        {
                            builder.AppendLine($"### {framework.Name}");
                            builder.AppendLine("| Package | Current | Major | Minor | Patch | Transitive |");
                            builder.AppendLine("| - | - | - | - | - | - |");

                            foreach (var package in framework.Packages)
                            {
                                builder
                                    .Append($"| {package.Name} |")
                                    .Append($" {package.CurrentVersion} |")
                                    .Append($" {package.AvailableVersions.GetValueOrDefault(Severity.Major)} |")
                                    .Append($" {package.AvailableVersions.GetValueOrDefault(Severity.Minor)} |")
                                    .Append($" {package.AvailableVersions.GetValueOrDefault(Severity.Patch)} |")
                                    .Append($" {package.IsTransitive.ToString().ToLowerInvariant()} |")
                                    .AppendLine();
                            }
                        }
                    }

                    builder.AppendLine();
                }

                if (upToDate.Any())
                {
                    builder.AppendLine("# Up to date");

                    foreach (var project in upToDate)
                    {
                        AppendProjectInfo(builder, project);
                    }

                    builder.AppendLine();
                }
            }

            builder.AppendLine("***");
            builder.AppendLine($"_{AppInfo.AppName} {DateTimeOffset.UtcNow:yyyy-MM-dd HH:mm UTC}_");

            var directory = _fileSystem.Path.GetDirectoryName(path);
            if (!_fileSystem.Directory.Exists(directory))
                _fileSystem.Directory.CreateDirectory(directory);

            _fileSystem.File.WriteAllText(path, builder.ToString(), Encoding.UTF8);
        }

        private static void AppendProjectInfo(StringBuilder builder, Project project)
        {
{'fraction_non_alphanumeric': 0.1036531690140845, 'fraction_numerical': 0.00022007042253521127, 'mean_word_length': 1.2287886218734674, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '530770', 'n_tokens_mistral': 2134, 'n_tokens_neox': 1970, 'n_words': 385}