/// <summary>
 ///
 /// </summary>
 /// <param name="propertyName">The name of the property to be compared. For example: 'Logical Name'</param>
 /// <param name="comparisonCondition">The comparison condition code. You can use the ComparisonConditionCodes object to get the appropriate code for your usecase. For example. ComparisonCodes.EndsWith or 'END' .</param>
 /// <param name="value">The value to be compared against. For example: 'Timestamp' </param>
 public RuleExpression(string propertyName, ComparisonConditionEnum comparisonCondition, object value, bool caseSensitive = false)
 {
     PropertyName        = propertyName;
     ComparisonCondition = ComparisonConditionCodes.GetTextForEnum(comparisonCondition);
     ExpressionValue     = value;
     CaseSensitive       = caseSensitive;
 }
 public RuleExpression(DataStructureProperty property, ComparisonConditionEnum comparisonCondition, object value, bool caseSensitive = false)
 {
     switch (property)
     {
     case DataStructureProperty.notset:
     case DataStructureProperty.LogicalName:
     case DataStructureProperty.PhysicalName:
     case DataStructureProperty.Definition:
     case DataStructureProperty.Datatype:
     case DataStructureProperty.DatatypeName:
     case DataStructureProperty.DatatypeLength:
     case DataStructureProperty.TableName:
     case DataStructureProperty.DatabaseManagementSystem:
     default:
         PropertyName = Enum.GetName(typeof(DataStructureProperty), property);
         break;
     }
     ComparisonCondition = ComparisonConditionCodes.GetTextForEnum(comparisonCondition);
     ExpressionValue     = value;
     CaseSensitive       = caseSensitive;
 }
        public bool Evaluate(Object o)
        {
            object propertyValue = GetPropertyValue(o);

            if (propertyValue == null)
            {
                throw new Exception($"Property '{PropertyName}' not found on object '{o.ToString()}'");
            }

            TypeCode expressionValueTypeCode = Type.GetTypeCode(ExpressionValue.GetType());
            TypeCode propertyValueTypeCode   = Type.GetTypeCode(propertyValue.GetType());
            bool     typeCodesMatch          = expressionValueTypeCode == propertyValueTypeCode;

            string propertyValueAsString   = propertyValue.ToString();
            string expressionValueAsString = ExpressionValue.ToString();

            if (CaseSensitive)
            {
                propertyValueAsString   = propertyValueAsString.ToLower();
                expressionValueAsString = expressionValueAsString.ToLower();
            }

            switch (ComparisonConditionCodes.GetEnumFromText(ComparisonCondition))
            {
            case ComparisonConditionEnum.EqualTo:
                return(propertyValueAsString.IsEqualTo(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.EqualToAny:
                return(propertyValueAsString.IsEqualToAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.NotEqual:
                return(!propertyValueAsString.IsEqualTo(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.NotEqualToAny:
                return(!propertyValueAsString.IsEqualToAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.Contains:
                return(propertyValueAsString.Contains(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.ContainsAny:
                return(propertyValueAsString.ContainsAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.DoesNotContain:
                return(!propertyValueAsString.Contains(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.DoesNotContainAny:
                return(propertyValueAsString.ContainsAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.StartsWith:
                return(propertyValueAsString.StartsWith(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.StartWithAny:
                return(propertyValueAsString.StartsWithAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.DoesNotStartWith:
                return(!propertyValueAsString.StartsWith(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.DoesNotStartWithAny:
                return(!propertyValueAsString.StartsWithAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.EndsWith:
                return(propertyValueAsString.EndsWith(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.EndsWithAny:
                return(propertyValueAsString.EndsWithAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.DoesNotEndWith:
                return(!propertyValueAsString.EndsWith(expressionValueAsString, CaseSensitive));

            case ComparisonConditionEnum.DoesNotEndWithAny:
                return(!propertyValueAsString.EndsWithAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.GreaterThan:
                if (typeCodesMatch)
                {
                    switch (propertyValueTypeCode)
                    {
                    case TypeCode.Boolean:
                        break;

                    case TypeCode.Byte:
                        break;

                    case TypeCode.Char:
                        break;

                    case TypeCode.DateTime:
                        break;

                    case TypeCode.DBNull:
                        break;

                    case TypeCode.Decimal:
                        break;

                    case TypeCode.Double:
                        break;

                    case TypeCode.Empty:
                        break;

                    case TypeCode.Int16:
                    case TypeCode.Int32:
                    case TypeCode.Int64:
                    case TypeCode.UInt16:
                    case TypeCode.UInt32:
                    case TypeCode.UInt64:
                        return(System.Convert.ToInt64(propertyValue) > System.Convert.ToInt64(ExpressionValue));

                    case TypeCode.Object:
                        break;

                    case TypeCode.SByte:
                        break;

                    case TypeCode.Single:
                        break;

                    case TypeCode.String:
                        break;

                    default:
                        break;
                    }
                }

                return(propertyValueAsString.IsGreaterThan(expressionValueAsString));

            case ComparisonConditionEnum.GreaterThanOrEqualTo:
                return(propertyValueAsString.IsGreaterThanOrEqualTo(expressionValueAsString));

            case ComparisonConditionEnum.GreaterThanAny:
                return(propertyValueAsString.IsGreaterThanAnyOfTheFollowing(expressionValueAsString.Split(';')));

            case ComparisonConditionEnum.GreaterThanOrEqualToAny:
                return(propertyValueAsString.IsGreaterThanOrEqualToAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            case ComparisonConditionEnum.LessThan:
                if (typeCodesMatch)
                {
                    switch (propertyValueTypeCode)
                    {
                    case TypeCode.Boolean:
                        break;

                    case TypeCode.Byte:
                        break;

                    case TypeCode.Char:
                        break;

                    case TypeCode.DateTime:
                        break;

                    case TypeCode.DBNull:
                        break;

                    case TypeCode.Decimal:
                        break;

                    case TypeCode.Double:
                        break;

                    case TypeCode.Empty:
                        break;

                    case TypeCode.Int16:
                    case TypeCode.Int32:
                    case TypeCode.Int64:
                    case TypeCode.UInt16:
                    case TypeCode.UInt32:
                    case TypeCode.UInt64:
                        return(System.Convert.ToInt64(propertyValue) < System.Convert.ToInt64(ExpressionValue));

                    case TypeCode.Object:
                        break;

                    case TypeCode.SByte:
                        break;

                    case TypeCode.Single:
                        break;

                    case TypeCode.String:
                        break;

                    default:
                        break;
                    }
                }
                return(propertyValueAsString.IsLessThan(expressionValueAsString));

            //less than any
            case ComparisonConditionEnum.LessThanAny:
                return(propertyValueAsString.IsLessThanAnyOfTheFollowing(expressionValueAsString.Split(';')));

            //less than or equal to any
            case ComparisonConditionEnum.LessThanOrEqualToAny:
                return(propertyValueAsString.IsLessThanOrEqualToAnyOfTheFollowing(expressionValueAsString.Split(';'), CaseSensitive));

            default:
                throw new Exception("Invalid comparison condition code");
            }
        }