<commit_before>﻿using NDesk.Options;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace Dasher.Schema.Generation
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Environment.ExitCode = (int)new Program().GenerateSchema(args);
            }
            catch (SchemaGenerationException e)
            {
                // Visual Studio parseable format
                Console.WriteLine("Dasher.Schema.Generation.exe : error: " + "Error generating schema for " + e.TargetType + ": " + e.Message);
                Environment.ExitCode = (int)ReturnCode.EXIT_ERROR;
            }
            catch (Exception e)
            {
                // Visual Studio parseable format
                Console.WriteLine("Dasher.Schema.Generation.exe : error: " + e.ToString());
                Environment.ExitCode = (int)ReturnCode.EXIT_ERROR;
            }
        }

        private enum ReturnCode
        {
            EXIT_SUCCESS = 0,
            EXIT_ERROR = 1
        };

        private string targetPath = null;
        private string targetDir = null;
        private string projectDir = null;
        private bool debug = false;
        private bool help = false;

        private ReturnCode GenerateSchema(string[] args)
        {
            var optionSet = new OptionSet() {
                                { "targetPath=", o => targetPath = o },
                                { "targetDir=",  o => targetDir = o },
                                { "projectDir=",  o => projectDir = o },
                                { "debug",   v => debug = v != null },
                                { "h|?|help",   v => help = v != null },
                                };

            List<string> extra = optionSet.Parse(args);


            if (help)
            {
                Usage();
                return ReturnCode.EXIT_SUCCESS;
            }

            if (debug)
                Debugger.Launch();

            if (targetPath == null || targetDir == null || projectDir == null)
            {
                // This format makes it show up properly in the VS Error window.
                Console.WriteLine("Dasher.Schema.Generation.exe : error: Incorrect command line arguments.");
                Usage();
                return ReturnCode.EXIT_ERROR;
            }

            var assembly = Assembly.LoadFrom(targetPath);

            var sendMessageTypes = new HashSet<Type>();
            var receiveMessageTypes = new HashSet<Type>();

            // TODO this is verbose.  Tidy up using Linq?
            foreach (Type t in assembly.GetTypes())
            {
                foreach (var attribute in t.GetCustomAttributes())
                {
                    if (attribute is SendMessageAttribute)
                    {
                        sendMessageTypes.Add(t);
                    }
                    if (attribute is ReceiveMessageAttribute)
                    {
                        receiveMessageTypes.Add(t);
                    }
                }
            }

            // Write to the project (ie source) dir and also the target (ie bin) dir.
            // This ensures the manifest is checked into source control but is also
            // can be bundled with the application if needed.
            writeToAppManifest(targetDir, sendMessageTypes, receiveMessageTypes);
            writeToAppManifest(projectDir, sendMessageTypes, receiveMessageTypes);

            return ReturnCode.EXIT_SUCCESS;
        }

        private void writeToAppManifest(string dirName, HashSet<Type> sendMessageTypes, HashSet<Type> receiveMessageTypes)
        {
            XDocument doc;
            // Create a file with a root element if the manifest doesn't exist.
            // This should only happen in testing.
            string appManifestFileName = dirName + "App.manifest";
            XElement appElement;
            if (File.Exists(appManifestFileName))
            {<commit_msg>Skip attributes from base class<commit_after>﻿using NDesk.Options;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml.Linq;

namespace Dasher.Schema.Generation
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Environment.ExitCode = (int)new Program().GenerateSchema(args);
            }
            catch (SchemaGenerationException e)
            {
                // Visual Studio parseable format
                Console.WriteLine("Dasher.Schema.Generation.exe : error: " + "Error generating schema for " + e.TargetType + ": " + e.Message);
                Environment.ExitCode = (int)ReturnCode.EXIT_ERROR;
            }
            catch (Exception e)
            {
                // Visual Studio parseable format
                Console.WriteLine("Dasher.Schema.Generation.exe : error: " + e.ToString());
                Environment.ExitCode = (int)ReturnCode.EXIT_ERROR;
            }
        }

        private enum ReturnCode
        {
            EXIT_SUCCESS = 0,
            EXIT_ERROR = 1
        };

        private string targetPath = null;
        private string targetDir = null;
        private string projectDir = null;
        private bool debug = false;
        private bool help = false;

        private ReturnCode GenerateSchema(string[] args)
        {
            var optionSet = new OptionSet() {
                                { "targetPath=", o => targetPath = o },
                                { "targetDir=",  o => targetDir = o },
                                { "projectDir=",  o => projectDir = o },
                                { "debug",   v => debug = v != null },
                                { "h|?|help",   v => help = v != null },
                                };

            List<string> extra = optionSet.Parse(args);


            if (help)
            {
                Usage();
                return ReturnCode.EXIT_SUCCESS;
            }

            if (debug)
                Debugger.Launch();

            if (targetPath == null || targetDir == null || projectDir == null)
            {
                // This format makes it show up properly in the VS Error window.
                Console.WriteLine("Dasher.Schema.Generation.exe : error: Incorrect command line arguments.");
                Usage();
                return ReturnCode.EXIT_ERROR;
            }

            var assembly = Assembly.LoadFrom(targetPath);

            var sendMessageTypes = new HashSet<Type>();
            var receiveMessageTypes = new HashSet<Type>();

            // TODO this is verbose.  Tidy up using Linq?
            foreach (Type t in assembly.GetTypes())
            {
                foreach (var attribute in t.GetCustomAttributes(false))
                {
                    if (attribute is SendMessageAttribute)
                    {
                        sendMessageTypes.Add(t);
                    }
                    if (attribute is ReceiveMessageAttribute)
                    {
                        receiveMessageTypes.Add(t);
                    }
                }
            }

            // Write to the project (ie source) dir and also the target (ie bin) dir.
            // This ensures the manifest is checked into source control but is also
            // can be bundled with the application if needed.
            writeToAppManifest(targetDir, sendMessageTypes, receiveMessageTypes);
            writeToAppManifest(projectDir, sendMessageTypes, receiveMessageTypes);

            return ReturnCode.EXIT_SUCCESS;
        }

        private void writeToAppManifest(string dirName, HashSet<Type> sendMessageTypes, HashSet<Type> receiveMessageTypes)
        {
            XDocument doc;
            // Create a file with a root element if the manifest doesn't exist.
            // This should only happen in testing.
            string appManifestFileName = dirName + "App.manifest";
            XElement appElement;
            if (File.Exists(appManifestFileName))
            {
{'fraction_non_alphanumeric': 0.08419015362283779, 'fraction_numerical': 0.00048385145760251603, 'mean_word_length': 1.4225021974802228, 'pattern_counts': {'":': 2, '<': 13, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1767200', 'n_tokens_mistral': 1981, 'n_tokens_neox': 1886, 'n_words': 544}