/// <summary>
 /// Creates a configuratino from the builder.
 /// </summary>
 /// <param name="builder"></param>
 public StreamDeckConfiguration(StreamDeckConfigurationBuilder builder)
 {
     this.Actions                  = builder.Actions.Select(x => new ActionDefinition(x)).ToList();
     this.Author                   = builder.Author;
     this.CategoryIcon             = builder.CategoryIcon;
     this.CategoryName             = builder.CategoryName;
     this.Description              = builder.CategoryName;
     this.Icon                     = builder.Icon;
     this.MinimumStreamDeckVersion = builder.MinimumStreamDeckVersion;
     this.Name                     = builder.Name;
     this.OS      = builder.OS;
     this.Url     = builder.Url;
     this.Version = builder.Version;
 }
        /// <summary>
        /// Configure all the required services
        /// </summary>
        /// <param name="builder">the builder to configure for streamdeck plugin hosting</param>
        /// <param name="args">the commandline arguments</param>
        /// <param name="configure">a callback for configuring actions and manifest details.</param>
        /// <returns>the passed in host builder for fullent api usage.</returns>
        public static IHostBuilder ConfigureStreamDeck(this IHostBuilder builder, string[] args, Action <StreamDeckConfigurationBuilder> configure)
        {
            var callingAssembly = Assembly.GetCallingAssembly();

            // switch between local development host that provides an embedded web service, api and application to debug/test application against
            // add option to also detect build time helpers calls to do things like expost manifests etc early

            var parsedArguments = Args.Parse <CommandlineArguments>(args);

            if (parsedArguments.Break == true && !Debugger.IsAttached)
            {
                Debugger.Launch();
            }

            var runInMemory  = !parsedArguments.TryGetStartupArguments(out var registrationArgs);
            var exportConfig = parsedArguments.TryGetExportConfigArguments(out var exportConfigSettings);

            if (exportConfig)
            {
                builder.ConfigureLogging(c => c.ClearProviders());
            }


            // we detect is we want to export manifest if we do we add the manifest host so when run executes it write out the manifest file and then exits the process
            // lest just scan for all actions
            builder.ConfigureServices(s =>
            {
                if (exportConfig)
                {
                    exportConfigSettings.CodePath = exportConfigSettings.CodePath ?? Assembly.GetEntryAssembly().Location;
                    s.AddSingleton(exportConfigSettings);
                    s.AddSingleton <IHostedService, StreamDeckConfigHost>();
                }
                else
                {
                    s.AddSingleton <IHostedService, StreamDeckHost>();
                }

                s.AddTransient <EventManager>();

                s.AddSingleton <StreamDeckPluginManager>();
                s.AddSingleton <IPluginManager>(c => c.GetRequiredService <StreamDeckPluginManager>());
                s.AddSingleton(typeof(IPluginManager <>), typeof(StreamDeckPluginManager <>));

                s.AddScoped <IActionManagerProvider, StreamDeckActionManagerProvider>();

                s.AddScoped(c => c.GetRequiredService <IActionManagerProvider>().CurrrentActionManager);
                s.AddScoped(typeof(IActionManager <>), typeof(StreamDeckActionManager <>));

                var configBuilder = new StreamDeckConfigurationBuilder(s, callingAssembly);
                configure?.Invoke(configBuilder);
                s.AddSingleton <IStreamDeckConfiguration>(sp =>
                {
                    return(configBuilder.Build());
                });
                if (!exportConfig)
                {
                    if (runInMemory)
                    {
                        s.AddSingleton <IStreamDeckConnection, StreamDeckEmulator>();
                    }
                    else
                    {
                        s.AddSingleton(registrationArgs);
                        s.AddSingleton <IStreamDeckConnection, StreamDeckConnection>();
                    }
                }
            });

            return(builder);
        }