private async Task <IPreprocessedRule> LoadAndValidateRule(string ruleName, string filePath, CancellationToken cancellationToken)
        {
            var engineLogger = new EngineWrapperLogger(_logger);

            var(preprocessedRule, _) = await RuleFileParser.ReadFile(filePath, engineLogger, cancellationToken);

            try
            {
                var rule = new Engine.ScriptedRuleWrapper(ruleName, preprocessedRule, engineLogger);
                var(success, diagnostics) = rule.Verify();
                if (!success)
                {
                    var messages = string.Join('\n', diagnostics.Select(d => d.ToString()));
                    if (!string.IsNullOrEmpty(messages))
                    {
                        _logger.WriteError($"Errors in the rule file {filePath}:\n{messages}");
                    }

                    return(null);
                }
            }
            catch
            {
                return(null);
            }

            // Rule file is valid
            return(preprocessedRule);
        }
        internal async Task <bool> AddAsync(InstanceName instance, string ruleName, string filePath, CancellationToken cancellationToken)
        {
            _logger.WriteInfo($"Validate rule file {filePath}");

            var engineLogger = new EngineWrapperLogger(_logger);

            var(preprocessedRule, _) = await RuleFileParser.ReadFile(filePath, engineLogger, cancellationToken);

            try
            {
                var rule = new Engine.ScriptedRuleWrapper(ruleName, preprocessedRule, engineLogger);
                var(success, diagnostics) = rule.Verify();
                if (success)
                {
                    _logger.WriteInfo($"Rule file is valid");
                }
                else
                {
                    _logger.WriteInfo($"Rule file is invalid");
                    var messages = string.Join('\n', diagnostics.Select(d => d.ToString()));
                    if (!string.IsNullOrEmpty(messages))
                    {
                        _logger.WriteError($"Errors in the rule file {filePath}:\n{messages}");
                    }

                    return(false);
                }
            }
            catch
            {
                _logger.WriteInfo($"Rule file is invalid");
                return(false);
            }

            _logger.WriteVerbose($"Layout rule files");
            var inMemoryFiles = await PackagingFilesAsync(ruleName, preprocessedRule);

            _logger.WriteInfo($"Packaging rule {ruleName} complete.");

            _logger.WriteVerbose($"Uploading rule files to {instance.PlainName}");
            bool ok = await UploadRuleFilesAsync(instance, ruleName, inMemoryFiles, cancellationToken);

            if (ok)
            {
                _logger.WriteInfo($"All {ruleName} files successfully uploaded to {instance.PlainName}.");
            }

            if (preprocessedRule.Impersonate)
            {
                _logger.WriteInfo($"Configure {ruleName} to execute impersonated.");
                ok &= await ConfigureAsync(instance, ruleName, impersonate : true, cancellationToken : cancellationToken);

                if (ok)
                {
                    _logger.WriteInfo($"Updated {ruleName} configuration successfully.");
                }
            }

            return(ok);
        }