<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using TsActivexGen.Util;
using static System.IO.Path;
using static System.IO.File;
using static System.Windows.MessageBoxButton;
using static System.Windows.MessageBoxResult;
using System.Diagnostics;
using static System.Reflection.Assembly;
using System.Windows.Data;
using System.Collections.ObjectModel;
using static TsActivexGen.Wpf.Functions;
using System.IO;
using static TsActivexGen.Functions;
using static TsActivexGen.Wpf.Misc;
using static System.Environment;
using TsActivexGen.tlibuilder;
using TsActivexGen.idlbuilder;
using static TsActivexGen.idlbuilder.Context;
using System.Windows.Controls;
using static System.StringComparison;

namespace TsActivexGen.Wpf {
    public partial class MainWindow : Window {
        ObservableCollection<DiskOutputDetails> fileList = new ObservableCollection<DiskOutputDetails>();
        TextBox txbFileBaseName;
        TextBox txbAuthorName;
        TextBox txbAuthorURL;

        public MainWindow() {
            InitializeComponent();

            //TODO enable sorting on this datagrid such that selected items are always on top
            dgTypeLibs.ItemsSource = TypeLibDetails.FromRegistry.Value;

            btnGenerate.Click += (s, e) => generateNSSet();

            txbFilter.TextChanged += (s, e) => applyFilter();

            //we're setting this in code because it's easier to do so than in XAML
            txbKeywords.Text = @"ole automation
scripting runtime
wmi scripting
activex data objects 6.1
access database engine
microsoft xml, v6.0
microsoft access 14.0 object library
microsoft excel
microsoft word
microsoft powerpoint
microsoft outlook 14.0 object library
infopath 3.0 type library
fax service extended com library
internet controls
shell controls and automation
speech
acquisition";

            brOutputFolder.Path = Combine(GetDirectoryName(GetEntryAssembly().Location), "typings");
            brOutputFolder.SelectionChanged += updateOptions;

            brDoxygenXMLFolder.Path = new[] { "../../../idlbuilder/output/xml", "output/xml" }.Select(x => GetFullPath(Combine(GetDirectoryName(GetEntryAssembly().Location), x))).FirstOrDefault(x => Directory.Exists(x));

            dtgFiles.ItemsSource = fileList;

            lbFilePerNamespace.SelectionChanged += (sender, e) => {
                if ((sender as ListBox).SelectedValue<bool>()) {
                    var current = fileList.FirstOrDefault();
                    fileList.Clear();
                    current?.NamespaceOutputs.SelectKVP((name, nsOutput) => {
                        var ret = DiskOutputDetails.Create(name, nsOutput);
                        ret.IsActiveX = current.IsActiveX;
                        ret.OutputFolderRoot = brOutputFolder.Path;
                        ret.IsPackage = lbPackageForDefinitelyTyped.SelectedValue<bool>();
                        return ret;
                    }).AddRangeTo(fileList);
                } else {
                    var current = fileList.Where(x => x != null).ToList();
                    fileList.Clear();
                    if (current.Any()) {
                        var first = current.First();
                        var ret = DiskOutputDetails.Create(first.Name, first.SingleOutput);
                        ret.IsActiveX = first.IsActiveX;
                        ret.OutputFolderRoot = first.OutputFolderRoot;
                        ret.IsPackage = lbPackageForDefinitelyTyped.SelectedValue<bool>();
                        current.Select(x => KVP(x.Name, x.SingleOutput)).AddRangeTo(ret.NamespaceOutputs);
                        fileList.Add(ret);
                    }
                }
            };

            lbPackageForDefinitelyTyped.SelectionChanged += updateOptions;

            btnOutput.Click += (s, e) => {
                var toOutput = dtgFiles.Items<DiskOutputDetails>().Where(x => x.WriteOutput && !x.Name.IsNullOrEmpty()).ToList();
                if (toOutput.None()) { return; }

                Directory.CreateDirectory(brOutputFolder.Path);

                string selectedPath = "";

                if (lbPackageForDefinitelyTyped.SelectedValue<bool>()) {
                    if (!writePackages(ref selectedPath)) { return; }
                } else if (lbFilePerNamespace.SelectedValue<bool>()) {
                    toOutput.ForEach(x => WriteAllText(x.SingleFilePath, x.SingleOutput.MainFile));
                    selectedPath = toOutput.First().SingleFilePath;
                } else {
                    var first = toOutput.First();
                    var ts = first.NamespaceOutputs.First().Value.MergedNominalTypes + NewLine + first.NamespaceOutputs.JoinedKVP((name, nsOutput) => nsOutput.LocalTypes, NewLine);
                    WriteAllText(first.SingleFilePath, ts);
                    selectedPath = first.SingleFilePath;
                }

                var psi = new ProcessStartInfo("explorer.exe", $"/n /e,/select,\"{selectedPath}\"");
                Process.Start(psi);
            };

            btnClearFiles.Click += (s, e) => {
                tlbGenerator = new TlbInf32Generator();
                fileList.Clear();
            };

            void RunTests(IEnumerable<string> jsonPaths) =>
                jsonPaths.ForEach(x => {
                    RunCommandlineAsync($"tsc -p {x} && tslint -p {x}");
                });

            btnTest.Click += (s, e) => RunTests(Directory.EnumerateFiles(brOutputFolder.Path, "tsconfig.json", SearchOption.AllDirectories));
            btnTestListed.Click += (s, e) => RunTests(fileList.Select(x => Combine(x.PackagePath, "tsconfig.json")));
        }

        private void updateOptions(object s, EventArgs e) => dtgFiles.Items<DiskOutputDetails>().ForEach(x => {
            x.OutputFolderRoot = brOutputFolder.Path;
            x.IsPackage = lbPackageForDefinitelyTyped.SelectedValue<bool>();
        });

        private bool createFile(string path) {
            if (!Exists(path)) { return true; }
            return MessageBox.Show($"Overwrite '{path}`?", "", YesNo) == Yes;
        }

        private bool writePackages(ref string selectedPath) {
            var toOutput = dtgFiles.Items<DiskOutputDetails>().Where(x => x.WriteOutput && !x.Name.IsNullOrEmpty()).ToList();

            //package for DefinitelyTyped

            //prompt about missing common details
            var missingCommon = new(string description, string value)[] { ("author name", txbAuthorName.Text), ("author URL", txbAuthorURL.Text) }.Where(x => x.value.IsNullOrEmpty());
            var errors = new List<(string description, string library)>();
            foreach (var x in toOutput) {
                if (x.MajorVersion == 0 && x.MinorVersion == 0) { errors.Add("version", x.Name); }
                if (x.LibraryUrl.IsNullOrEmpty()) { errors.Add("library url", x.Name); }
            }
            var missingDetails = errors.GroupBy(x => x.description, (description, x) => (description: description, libs: x.Joined(", ", y => y.library))).ToList();
<commit_msg>Fix -p to --project tslint option<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using TsActivexGen.Util;
using static System.IO.Path;
using static System.IO.File;
using static System.Windows.MessageBoxButton;
using static System.Windows.MessageBoxResult;
using System.Diagnostics;
using static System.Reflection.Assembly;
using System.Windows.Data;
using System.Collections.ObjectModel;
using static TsActivexGen.Wpf.Functions;
using System.IO;
using static TsActivexGen.Functions;
using static TsActivexGen.Wpf.Misc;
using static System.Environment;
using TsActivexGen.tlibuilder;
using TsActivexGen.idlbuilder;
using static TsActivexGen.idlbuilder.Context;
using System.Windows.Controls;
using static System.StringComparison;

namespace TsActivexGen.Wpf {
    public partial class MainWindow : Window {
        ObservableCollection<DiskOutputDetails> fileList = new ObservableCollection<DiskOutputDetails>();
        TextBox txbFileBaseName;
        TextBox txbAuthorName;
        TextBox txbAuthorURL;

        public MainWindow() {
            InitializeComponent();

            //TODO enable sorting on this datagrid such that selected items are always on top
            dgTypeLibs.ItemsSource = TypeLibDetails.FromRegistry.Value;

            btnGenerate.Click += (s, e) => generateNSSet();

            txbFilter.TextChanged += (s, e) => applyFilter();

            //we're setting this in code because it's easier to do so than in XAML
            txbKeywords.Text = @"ole automation
scripting runtime
wmi scripting
activex data objects 6.1
access database engine
microsoft xml, v6.0
microsoft access 14.0 object library
microsoft excel
microsoft word
microsoft powerpoint
microsoft outlook 14.0 object library
infopath 3.0 type library
fax service extended com library
internet controls
shell controls and automation
speech
acquisition";

            brOutputFolder.Path = Combine(GetDirectoryName(GetEntryAssembly().Location), "typings");
            brOutputFolder.SelectionChanged += updateOptions;

            brDoxygenXMLFolder.Path = new[] { "../../../idlbuilder/output/xml", "output/xml" }.Select(x => GetFullPath(Combine(GetDirectoryName(GetEntryAssembly().Location), x))).FirstOrDefault(x => Directory.Exists(x));

            dtgFiles.ItemsSource = fileList;

            lbFilePerNamespace.SelectionChanged += (sender, e) => {
                if ((sender as ListBox).SelectedValue<bool>()) {
                    var current = fileList.FirstOrDefault();
                    fileList.Clear();
                    current?.NamespaceOutputs.SelectKVP((name, nsOutput) => {
                        var ret = DiskOutputDetails.Create(name, nsOutput);
                        ret.IsActiveX = current.IsActiveX;
                        ret.OutputFolderRoot = brOutputFolder.Path;
                        ret.IsPackage = lbPackageForDefinitelyTyped.SelectedValue<bool>();
                        return ret;
                    }).AddRangeTo(fileList);
                } else {
                    var current = fileList.Where(x => x != null).ToList();
                    fileList.Clear();
                    if (current.Any()) {
                        var first = current.First();
                        var ret = DiskOutputDetails.Create(first.Name, first.SingleOutput);
                        ret.IsActiveX = first.IsActiveX;
                        ret.OutputFolderRoot = first.OutputFolderRoot;
                        ret.IsPackage = lbPackageForDefinitelyTyped.SelectedValue<bool>();
                        current.Select(x => KVP(x.Name, x.SingleOutput)).AddRangeTo(ret.NamespaceOutputs);
                        fileList.Add(ret);
                    }
                }
            };

            lbPackageForDefinitelyTyped.SelectionChanged += updateOptions;

            btnOutput.Click += (s, e) => {
                var toOutput = dtgFiles.Items<DiskOutputDetails>().Where(x => x.WriteOutput && !x.Name.IsNullOrEmpty()).ToList();
                if (toOutput.None()) { return; }

                Directory.CreateDirectory(brOutputFolder.Path);

                string selectedPath = "";

                if (lbPackageForDefinitelyTyped.SelectedValue<bool>()) {
                    if (!writePackages(ref selectedPath)) { return; }
                } else if (lbFilePerNamespace.SelectedValue<bool>()) {
                    toOutput.ForEach(x => WriteAllText(x.SingleFilePath, x.SingleOutput.MainFile));
                    selectedPath = toOutput.First().SingleFilePath;
                } else {
                    var first = toOutput.First();
                    var ts = first.NamespaceOutputs.First().Value.MergedNominalTypes + NewLine + first.NamespaceOutputs.JoinedKVP((name, nsOutput) => nsOutput.LocalTypes, NewLine);
                    WriteAllText(first.SingleFilePath, ts);
                    selectedPath = first.SingleFilePath;
                }

                var psi = new ProcessStartInfo("explorer.exe", $"/n /e,/select,\"{selectedPath}\"");
                Process.Start(psi);
            };

            btnClearFiles.Click += (s, e) => {
                tlbGenerator = new TlbInf32Generator();
                fileList.Clear();
            };

            void RunTests(IEnumerable<string> jsonPaths) =>
                jsonPaths.ForEach(x => {
                    RunCommandlineAsync($"tsc -p {x} && tslint --project {x} --type-check");
                });

            btnTest.Click += (s, e) => RunTests(Directory.EnumerateFiles(brOutputFolder.Path, "tsconfig.json", SearchOption.AllDirectories));
            btnTestListed.Click += (s, e) => RunTests(fileList.Select(x => Combine(x.PackagePath, "tsconfig.json")));
        }

        private void updateOptions(object s, EventArgs e) => dtgFiles.Items<DiskOutputDetails>().ForEach(x => {
            x.OutputFolderRoot = brOutputFolder.Path;
            x.IsPackage = lbPackageForDefinitelyTyped.SelectedValue<bool>();
        });

        private bool createFile(string path) {
            if (!Exists(path)) { return true; }
            return MessageBox.Show($"Overwrite '{path}`?", "", YesNo) == Yes;
        }

        private bool writePackages(ref string selectedPath) {
            var toOutput = dtgFiles.Items<DiskOutputDetails>().Where(x => x.WriteOutput && !x.Name.IsNullOrEmpty()).ToList();

            //package for DefinitelyTyped

            //prompt about missing common details
            var missingCommon = new(string description, string value)[] { ("author name", txbAuthorName.Text), ("author URL", txbAuthorURL.Text) }.Where(x => x.value.IsNullOrEmpty());
            var errors = new List<(string description, string library)>();
            foreach (var x in toOutput) {
                if (x.MajorVersion == 0 && x.MinorVersion == 0) { errors.Add("version", x.Name); }
                if (x.LibraryUrl.IsNullOrEmpty()) { errors.Add("library url", x.Name); }
            }
            var missingDetails = errors.GroupBy(x => x.description, (description, x) => (description: description, libs: x.Joined(", ", y => y.library))).ToList();

{'fraction_non_alphanumeric': 0.1118060435699227, 'fraction_numerical': 0.0022487702037948, 'mean_word_length': 2.3095348837209304, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 79, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, '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': '5488095', 'n_tokens_mistral': 3808, 'n_tokens_neox': 3615, 'n_words': 818}