private EvaluationDetail <LdValue> Evaluate(User user, IFeatureStore featureStore, IList <FeatureRequestEvent> events,
                                                    EventFactory eventFactory)
        {
            if (!On)
            {
                return(GetOffValue(EvaluationReason.OffReason));
            }

            var prereqFailureReason = CheckPrerequisites(user, featureStore, events, eventFactory);

            if (prereqFailureReason != null)
            {
                return(GetOffValue(prereqFailureReason));
            }

            // Check to see if targets match
            if (Targets != null)
            {
                foreach (var target in Targets)
                {
                    foreach (var v in target.Values)
                    {
                        if (user.Key == v)
                        {
                            return(GetVariation(target.Variation, EvaluationReason.TargetMatchReason));
                        }
                    }
                }
            }
            // Now walk through the rules and see if any match
            if (Rules != null)
            {
                for (int i = 0; i < Rules.Count; i++)
                {
                    Rule rule = Rules[i];
                    if (rule.MatchesUser(user, featureStore))
                    {
                        return(GetValueForVariationOrRollout(rule, user,
                                                             EvaluationReason.RuleMatchReason(i, rule.Id)));
                    }
                }
            }
            // Walk through the fallthrough and see if it matches
            return(GetValueForVariationOrRollout(Fallthrough, user, EvaluationReason.FallthroughReason));
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            LdValue o = (LdValue)LdValueSerializer.Instance.ReadJson(reader, typeof(LdValue), LdValue.Null, serializer);

            if (o.IsNull)
            {
                return(null);
            }
            EvaluationReasonKind kind = (EvaluationReasonKind)Enum.Parse(typeof(EvaluationReasonKind), o.Get("kind").AsString);

            switch (kind)
            {
            case EvaluationReasonKind.OFF:
                return(EvaluationReason.OffReason);

            case EvaluationReasonKind.FALLTHROUGH:
                return(EvaluationReason.FallthroughReason);

            case EvaluationReasonKind.TARGET_MATCH:
                return(EvaluationReason.TargetMatchReason);

            case EvaluationReasonKind.RULE_MATCH:
                var index = o.Get("ruleIndex").AsInt;
                var id    = o.Get("ruleId").AsString;
                return(EvaluationReason.RuleMatchReason(index, id));

            case EvaluationReasonKind.PREREQUISITE_FAILED:
                var key = o.Get("prerequisiteKey").AsString;
                return(EvaluationReason.PrerequisiteFailedReason(key));

            case EvaluationReasonKind.ERROR:
                var errorKind = (EvaluationErrorKind)Enum.Parse(typeof(EvaluationErrorKind), o.Get("errorKind").AsString);
                return(EvaluationReason.ErrorReason(errorKind));
            }
            throw new ArgumentException();
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject o = serializer.Deserialize <JObject>(reader);

            if (o == null)
            {
                return(null);
            }
            EvaluationReasonKind kind = o.GetValue("kind").ToObject <EvaluationReasonKind>();

            switch (kind)
            {
            case EvaluationReasonKind.OFF:
                return(EvaluationReason.OffReason);

            case EvaluationReasonKind.FALLTHROUGH:
                return(EvaluationReason.FallthroughReason);

            case EvaluationReasonKind.TARGET_MATCH:
                return(EvaluationReason.TargetMatchReason);

            case EvaluationReasonKind.RULE_MATCH:
                var index = (int)o.GetValue("ruleIndex");
                var id    = (string)o.GetValue("ruleId");
                return(EvaluationReason.RuleMatchReason(index, id));

            case EvaluationReasonKind.PREREQUISITE_FAILED:
                var key = (string)o.GetValue("prerequisiteKey");
                return(EvaluationReason.PrerequisiteFailedReason(key));

            case EvaluationReasonKind.ERROR:
                var errorKind = o.GetValue("errorKind").ToObject <EvaluationErrorKind>();
                return(EvaluationReason.ErrorReason(errorKind));
            }
            throw new ArgumentException();
        }