<commit_before>﻿using System;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using Oxygenize.Generators;

namespace Oxygenize
{
    public class Oxygenize
    {
        private static readonly ConcurrentDictionary<string, Func<object>> SupportedTypes = new ConcurrentDictionary<string, Func<object>>(); 

        public static Oxygenize<T> For<T>() where T : new()
        {
            return new Oxygenize<T>();
        }

        /// <summary>
        /// Adds support for given custom type, which enables
        /// RandomStrategyGenerator to generate given value
        /// </summary>
        /// <param name="typeName">Type ToString() representation</param>
        /// <param name="valueToObtain">Function which will be used to obtain random value</param>
        public static void AddSupport(string typeName, Func<object> valueToObtain)
        {
            SupportedTypes.AddOrUpdate(typeName, valueToObtain, (s, func) => valueToObtain);
        }

        internal static object ObtainValue(string typeName)
        {
            Func<object> valueToObtain;
            if (!SupportedTypes.TryGetValue(typeName, out valueToObtain))
            {
                throw new ArgumentException("Cannot obtain a value of unregistered type.", "typeName");
            }

            return valueToObtain.Invoke();
        }
    }

    public class Oxygenize<T> where T : new()
    {
        private PropertyConfigurator<T> _configurator; 

        private GenerationStrategy _strategy = GenerationStrategy.Random;
        private int _arrayUpperBound = 1000;
        private bool _nullableReferenceTypes;
        private int _maxStringLength = 4000;
        private int _minStringLength;
        private Tuple<Type[], object[]> _constructorParameters;

        internal Oxygenize()
        {
            _configurator = new PropertyConfigurator<T>(this);
        }   

        /// <summary>
        /// Returns an instance of the given type
        /// </summary>
        public T Instance
        {
            get { return PopulateData(); }
        }

        private T PopulateData()
        {
            var configuration = new Configuration(_arrayUpperBound, _nullableReferenceTypes, _maxStringLength, _minStringLength, _constructorParameters);

            T instance;
            switch (_strategy)
            {
                case GenerationStrategy.Mixed:
                case GenerationStrategy.Custom:
                    instance = new CustomStrategyGenerator<T>(configuration).GetData();
                    break;
                case GenerationStrategy.Random:
                    instance = new RandomStrategyGenerator<T>(configuration).GetData();
                    break;
                default:
                    instance = new RandomStrategyGenerator<T>(configuration).GetData();
                    break;
            }

            return instance;
        }

        /// <summary>
        /// Sets the strategy used for data generation
        /// </summary>
        public Oxygenize<T> WithStrategy(GenerationStrategy strategy = GenerationStrategy.Random)
        {
            _strategy = strategy;
            return this;
        }

        /// <summary>
        /// Sets upper bound for arrays generation
        /// </summary>
        public Oxygenize<T> UpperBound(int upperBound)
        {
            _arrayUpperBound = upperBound;
            return this;
        }

        /// <summary>
        /// Determines whether reference types can be generated as null
        /// </summary>
        public Oxygenize<T> NullableReferenceTypes(bool areNullable)
        {
            _nullableReferenceTypes = areNullable;
            return this;
        }

        /// <summary>
        /// Sets maximum length of a generated string
        /// </summary>
        public Oxygenize<T> MaxStringLength(int maxLength)
        {
            _maxStringLength = maxLength;
            return this;
        }

        /// <summary>
        /// Sets minimal length of a generated string
        /// </summary>
        public Oxygenize<T> MinStringLength(int minLength)
        {
            _minStringLength = minLength;
            return this;
        }

        /// <summary>
        /// Sets a constructor which should be called when creating an instance
        /// </summary>
        /// <param name="types">Parameters types</param>
        /// <param name="values">Parameters values</param>
        public Oxygenize<T> WithConstructor(Type[] types, object[] values)
        {
            _constructorParameters = new Tuple<Type[], object[]>(types, values);
            return this;
        }

        public PropertyConfigurator<T> Configure()
        {
            return _configurator;
        }  
    }<commit_msg>custom-data-generation Throwing an exception when trying to configure an instance for RandomGenerationStrategy<commit_after>﻿using System;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using Oxygenize.Generators;

namespace Oxygenize
{
    public class Oxygenize
    {
        private static readonly ConcurrentDictionary<string, Func<object>> SupportedTypes = new ConcurrentDictionary<string, Func<object>>(); 

        public static Oxygenize<T> For<T>() where T : new()
        {
            return new Oxygenize<T>();
        }

        /// <summary>
        /// Adds support for given custom type, which enables
        /// RandomStrategyGenerator to generate given value
        /// </summary>
        /// <param name="typeName">Type ToString() representation</param>
        /// <param name="valueToObtain">Function which will be used to obtain random value</param>
        public static void AddSupport(string typeName, Func<object> valueToObtain)
        {
            SupportedTypes.AddOrUpdate(typeName, valueToObtain, (s, func) => valueToObtain);
        }

        internal static object ObtainValue(string typeName)
        {
            Func<object> valueToObtain;
            if (!SupportedTypes.TryGetValue(typeName, out valueToObtain))
            {
                throw new ArgumentException("Cannot obtain a value of unregistered type.", "typeName");
            }

            return valueToObtain.Invoke();
        }
    }

    public class Oxygenize<T> where T : new()
    {
        private PropertyConfigurator<T> _configurator; 

        private GenerationStrategy _strategy = GenerationStrategy.Random;
        private int _arrayUpperBound = 1000;
        private bool _nullableReferenceTypes;
        private int _maxStringLength = 4000;
        private int _minStringLength;
        private Tuple<Type[], object[]> _constructorParameters;

        internal Oxygenize()
        {
            _configurator = new PropertyConfigurator<T>(this);
        }   

        /// <summary>
        /// Returns an instance of the given type
        /// </summary>
        public T Instance
        {
            get { return PopulateData(); }
        }

        private T PopulateData()
        {
            var configuration = new Configuration(_arrayUpperBound, _nullableReferenceTypes, _maxStringLength, _minStringLength, _constructorParameters);

            T instance;
            switch (_strategy)
            {
                case GenerationStrategy.Mixed:
                case GenerationStrategy.Custom:
                    instance = new CustomStrategyGenerator<T>(configuration).GetData();
                    break;
                case GenerationStrategy.Random:
                    instance = new RandomStrategyGenerator<T>(configuration).GetData();
                    break;
                default:
                    instance = new RandomStrategyGenerator<T>(configuration).GetData();
                    break;
            }

            return instance;
        }

        /// <summary>
        /// Sets the strategy used for data generation
        /// </summary>
        public Oxygenize<T> WithStrategy(GenerationStrategy strategy = GenerationStrategy.Random)
        {
            _strategy = strategy;
            return this;
        }

        /// <summary>
        /// Sets upper bound for arrays generation
        /// </summary>
        public Oxygenize<T> UpperBound(int upperBound)
        {
            _arrayUpperBound = upperBound;
            return this;
        }

        /// <summary>
        /// Determines whether reference types can be generated as null
        /// </summary>
        public Oxygenize<T> NullableReferenceTypes(bool areNullable)
        {
            _nullableReferenceTypes = areNullable;
            return this;
        }

        /// <summary>
        /// Sets maximum length of a generated string
        /// </summary>
        public Oxygenize<T> MaxStringLength(int maxLength)
        {
            _maxStringLength = maxLength;
            return this;
        }

        /// <summary>
        /// Sets minimal length of a generated string
        /// </summary>
        public Oxygenize<T> MinStringLength(int minLength)
        {
            _minStringLength = minLength;
            return this;
        }

        /// <summary>
        /// Sets a constructor which should be called when creating an instance
        /// </summary>
        /// <param name="types">Parameters types</param>
        /// <param name="values">Parameters values</param>
        public Oxygenize<T> WithConstructor(Type[] types, object[] values)
        {
            _constructorParameters = new Tuple<Type[], object[]>(types, values);
            return this;
        }

        public PropertyConfigurator<T> Configure()
        {
            if(_strategy == GenerationStrategy.Random)
                throw new InvalidOperationException("You cannot configure an instance for RandomGenerationStrategy.");

            return _configurator;
        }  
    }
{'fraction_non_alphanumeric': 0.08923483923483924, 'fraction_numerical': 0.001628001628001628, 'mean_word_length': 1.8415727088753975, 'pattern_counts': {'":': 0, '<': 99, '<?xml version=': 0, '>': 101, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '5862731', 'n_tokens_mistral': 2376, 'n_tokens_neox': 2315, 'n_words': 637}