<commit_before>﻿// Copyright 2005-2015 <NAME> & Contributors. All rights reserved. See doc/License.md in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using CommandLine.Infrastructure;

namespace CommandLine.Core
{
    static class SpecificationPropertyRules
    {
        public static readonly IEnumerable<Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>>> Lookup = new List<Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>>>
            {
                EnforceMutuallyExclusiveSet(),
                EnforceRequired(),
                EnforceRange()
            };

        private static Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>> EnforceMutuallyExclusiveSet()
        {
            return specProps =>
                {
                    var options = specProps
                            .Where(sp => sp.Specification.IsOption())
                            .Where(sp => ((OptionSpecification)sp.Specification).SetName.Length > 0
                                   && sp.Value.IsJust()
                                   && sp.Specification.GetSetName().Length > 0);
                    var groups = options.GroupBy(g => ((OptionSpecification)g.Specification).SetName);
                    if (groups.Count() > 1)
                    {
                        return options.Select(s => Maybe.Just<Error>(
                            new MutuallyExclusiveSetError(
                                NameInfo.FromOptionSpecification((OptionSpecification)s.Specification))));
                    }
                    return Enumerable.Empty<Nothing<Error>>();
                };
        }

        private static Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>> EnforceRequired()
        {
            return specProps =>
            {
                List<string> setsWithTrue =
                    specProps.Where(sp => sp.Specification.IsOption() && sp.Value.IsJust() && sp.Specification.Required)
                        .Select(x => x.Specification.GetSetName()).ToList();
                
                var requiredButEmpty =
                    specProps.Where(sp => sp.Value.IsNothing() && 
                                          sp.Specification.Required &&
                                          !setsWithTrue.Contains(sp.Specification.GetSetName())).ToList();
                    if (requiredButEmpty.Any()) {
                        return requiredButEmpty.Select(s => Maybe.Just<Error>(new MissingRequiredOptionError(
                            NameInfo.FromSpecification(s.Specification))));
                    }
                    return Enumerable.Empty<Nothing<Error>>();
                };
        }

        private static Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>> EnforceRange()
        {
            return specProps =>
                {
                    var options = specProps.Where(<commit_msg>:boom: Improving EnforceRequired() readability<commit_after>﻿// Copyright 2005-2015 <NAME> & Contributors. All rights reserved. See doc/License.md in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using CommandLine.Infrastructure;

namespace CommandLine.Core
{
    static class SpecificationPropertyRules
    {
        public static readonly IEnumerable<Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>>> Lookup = new List<Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>>>
            {
                EnforceMutuallyExclusiveSet(),
                EnforceRequired(),
                EnforceRange()
            };

        private static Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>> EnforceMutuallyExclusiveSet()
        {
            return specProps =>
                {
                    var options = specProps
                            .Where(sp => sp.Specification.IsOption())
                            .Where(sp => ((OptionSpecification)sp.Specification).SetName.Length > 0
                                   && sp.Value.IsJust()
                                   && sp.Specification.GetSetName().Length > 0);
                    var groups = options.GroupBy(g => ((OptionSpecification)g.Specification).SetName);
                    if (groups.Count() > 1)
                    {
                        return options.Select(s => Maybe.Just<Error>(
                            new MutuallyExclusiveSetError(
                                NameInfo.FromOptionSpecification((OptionSpecification)s.Specification))));
                    }
                    return Enumerable.Empty<Nothing<Error>>();
                };
        }

        private static Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>> EnforceRequired()
        {
            return specProps =>
            {
                List<string> setsWithTrue =
                    specProps
                        .Where(sp => sp.Specification.IsOption()
                            && sp.Value.IsJust() && sp.Specification.Required)
                        .Select(s => ((OptionSpecification)s.Specification).SetName).ToList();
                
                var requiredButEmpty =
                    specProps
                        .Where(sp => sp.Specification.IsOption())
                        .Where(sp => sp.Value.IsNothing()
                            && sp.Specification.Required
                            && !setsWithTrue.Contains(((OptionSpecification)sp.Specification).SetName))
                    .Concat(specProps
                        .Where(sp => sp.Specification.IsValue()
                            && sp.Value.IsNothing()
                            && sp.Specification.Required)).ToList();
                    if (requiredButEmpty.Any()) {
                        return requiredButEmpty.Select(s => Maybe.Just<Error>(new MissingRequiredOptionError(
                            NameInfo.FromSpecification(s.Specification))));
                    }
                    return Enumerable.Empty<Nothing<Error>>();
                };
        }

        private static Func<IEnumerable<SpecificationProperty>, IEnumerable<Maybe<Error>>> EnforceRange()
        {
            return specProps =>
                {
                    var options = specProps.Where(
{'fraction_non_alphanumeric': 0.09802088203210223, 'fraction_numerical': 0.003428393330216612, 'mean_word_length': 1.5702843412094514, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 93, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5136149', 'n_tokens_mistral': 1498, 'n_tokens_neox': 1402, 'n_words': 241}