internal MetricChangePointFeedback(FeedbackType type, string id, DateTimeOffset?createdTime, string userPrincipal, string metricId, FeedbackDimensionFilter dimensionFilter, DateTimeOffset startTime, DateTimeOffset endTime, ChangePointFeedbackValue valueInternal) : base(type, id, createdTime, userPrincipal, metricId, dimensionFilter)
 {
     StartTime     = startTime;
     EndTime       = endTime;
     ValueInternal = valueInternal;
     Type          = type;
 }
 internal ChangePointFeedback(FeedbackType feedbackType, Guid?feedbackId, DateTimeOffset?createdTime, string userPrincipal, Guid metricId, FeedbackDimensionFilter dimensionFilter, DateTimeOffset startTime, DateTimeOffset endTime, ChangePointFeedbackValue value) : base(feedbackType, feedbackId, createdTime, userPrincipal, metricId, dimensionFilter)
 {
     StartTime    = startTime;
     EndTime      = endTime;
     Value        = value;
     FeedbackType = feedbackType;
 }
        /// <summary>
        /// Initializes a new instance of <see cref="MetricsAdvisor.MetricChangePointFeedback"/> for mocking purposes.
        /// </summary>
        /// <param name="id">Sets the <see cref="MetricFeedback.Id"/> property.</param>
        /// <param name="createdOn">Sets the <see cref="MetricFeedback.CreatedOn"/> property.</param>
        /// <param name="userPrincipal">Sets the <see cref="MetricFeedback.UserPrincipal"/> property.</param>
        /// <param name="metricId">Sets the <see cref="MetricFeedback.MetricId"/> property.</param>
        /// <param name="dimensionKey">Sets the <see cref="MetricFeedback.DimensionKey"/> property.</param>
        /// <param name="startsOn">Sets the <see cref="MetricChangePointFeedback.StartsOn"/> property.</param>
        /// <param name="endsOn">Sets the <see cref="MetricChangePointFeedback.EndsOn"/> property.</param>
        /// <param name="changePointValue">Sets the <see cref="MetricChangePointFeedback.ChangePointValue"/> property.</param>
        /// <returns>A new instance of <see cref="MetricsAdvisor.MetricChangePointFeedback"/> for mocking purposes.</returns>
        public static MetricChangePointFeedback MetricChangePointFeedback(string id = null, DateTimeOffset?createdOn = null, string userPrincipal = null, string metricId = null, DimensionKey dimensionKey = null, DateTimeOffset startsOn = default, DateTimeOffset endsOn = default, ChangePointValue changePointValue = default)
        {
            Dictionary <string, string> dimensions = dimensionKey?.ToDictionary(key => key.Key, key => key.Value);
            FeedbackFilter           filter        = new FeedbackFilter(dimensions);
            ChangePointFeedbackValue feedbackValue = new ChangePointFeedbackValue(changePointValue);

            return(new MetricChangePointFeedback(MetricFeedbackKind.ChangePoint, id, createdOn, userPrincipal, metricId, filter, startsOn, endsOn, feedbackValue));
        }
        /// <summary> Initializes a new <see cref="MetricChangePointFeedback"/> instance. </summary>
        /// <param name="metricId"> The metric unique id. </param>
        /// <param name="dimensionFilter"> The dimension filter. </param>
        /// <param name="startTime"> The start timestamp of feedback timerange. </param>
        /// <param name="endTime"> The end timestamp of feedback timerange. When this is equal to <paramref name="startTime"/> it indicates a single timestamp. </param>
        /// <param name="value"> The <see cref="Models.ChangePointFeedbackValue"/> for the feedback. </param>
        internal MetricChangePointFeedback(string metricId, FeedbackDimensionFilter dimensionFilter, DateTimeOffset startTime, DateTimeOffset endTime, ChangePointFeedbackValue value) : base(metricId, dimensionFilter)
        {
            Argument.AssertNotNull(value, nameof(value));

            StartTime     = startTime;
            EndTime       = endTime;
            ValueInternal = value;
            Type          = Models.FeedbackType.ChangePoint;
        }
        /// <summary> Initializes a new <see cref="MetricChangePointFeedback"/> instance. </summary>
        /// <param name="metricId"> The metric unique id. </param>
        /// <param name="dimensionFilter"> The dimension filter. </param>
        /// <param name="startTime"> The start timestamp of feedback timerange. </param>
        /// <param name="endTime"> The end timestamp of feedback timerange. When this is equal to <paramref name="startTime"/> it indicates a single timestamp. </param>
        /// <param name="value"> The <see cref="Models.ChangePointValue"/> for the feedback. </param>
        /// <exception cref="ArgumentNullException"> <paramref name="dimensionFilter"/> or <paramref name="value"/> is null. </exception>
        public MetricChangePointFeedback(string metricId, FeedbackDimensionFilter dimensionFilter, DateTimeOffset startTime, DateTimeOffset endTime, ChangePointValue value) : base(metricId, dimensionFilter)
        {
            if (value == default)
            {
                throw new ArgumentNullException(nameof(value));
            }

            StartTime     = startTime;
            EndTime       = endTime;
            ValueInternal = new ChangePointFeedbackValue(value);
            Type          = FeedbackType.ChangePoint;
        }
        /// <summary> Initializes a new instance of ChangePointFeedback. </summary>
        /// <param name="metricId"> metric unique id. </param>
        /// <param name="dimensionFilter"> . </param>
        /// <param name="startTime"> the start timestamp of feedback timerange. </param>
        /// <param name="endTime"> the end timestamp of feedback timerange, when equals to startTime means only one timestamp. </param>
        /// <param name="value"> . </param>
        /// <exception cref="ArgumentNullException"> <paramref name="dimensionFilter"/> or <paramref name="value"/> is null. </exception>
        internal ChangePointFeedback(Guid metricId, FeedbackDimensionFilter dimensionFilter, DateTimeOffset startTime, DateTimeOffset endTime, ChangePointFeedbackValue value) : base(metricId, dimensionFilter)
        {
            if (dimensionFilter == null)
            {
                throw new ArgumentNullException(nameof(dimensionFilter));
            }
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }

            StartTime    = startTime;
            EndTime      = endTime;
            Value        = value;
            FeedbackType = Models.FeedbackType.ChangePoint;
        }
        internal static MetricChangePointFeedback DeserializeMetricChangePointFeedback(JsonElement element)
        {
            DateTimeOffset            startTime     = default;
            DateTimeOffset            endTime       = default;
            ChangePointFeedbackValue  value         = default;
            FeedbackType              feedbackType  = default;
            Optional <string>         feedbackId    = default;
            Optional <DateTimeOffset> createdTime   = default;
            Optional <string>         userPrincipal = default;
            string metricId = default;
            FeedbackDimensionFilter dimensionFilter = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("startTime"))
                {
                    startTime = property.Value.GetDateTimeOffset("O");
                    continue;
                }
                if (property.NameEquals("endTime"))
                {
                    endTime = property.Value.GetDateTimeOffset("O");
                    continue;
                }
                if (property.NameEquals("value"))
                {
                    value = ChangePointFeedbackValue.DeserializeChangePointFeedbackValue(property.Value);
                    continue;
                }
                if (property.NameEquals("feedbackType"))
                {
                    feedbackType = new FeedbackType(property.Value.GetString());
                    continue;
                }
                if (property.NameEquals("feedbackId"))
                {
                    feedbackId = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("createdTime"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    createdTime = property.Value.GetDateTimeOffset("O");
                    continue;
                }
                if (property.NameEquals("userPrincipal"))
                {
                    userPrincipal = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("metricId"))
                {
                    metricId = property.Value.GetString();
                    continue;
                }
                if (property.NameEquals("dimensionFilter"))
                {
                    dimensionFilter = FeedbackDimensionFilter.DeserializeFeedbackDimensionFilter(property.Value);
                    continue;
                }
            }
            return(new MetricChangePointFeedback(feedbackType, feedbackId.Value, Optional.ToNullable(createdTime), userPrincipal.Value, metricId, dimensionFilter, startTime, endTime, value));
        }