// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AWS.Deploy.Common.Recipes.Validation;
using Newtonsoft.Json;
namespace AWS.Deploy.Common.Recipes
{
/// , and methods
public partial class OptionSettingItem
{
public T? GetValue(IDictionary replacementTokens, IDictionary? displayableOptionSettings = null)
{
var value = GetValue(replacementTokens, displayableOptionSettings);
return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value));
}
public object GetValue(IDictionary replacementTokens, IDictionary? displayableOptionSettings = null)
{
if (_value != null)
{
return _value;
}
if (Type == OptionSettingValueType.Object)
{
var objectValue = new Dictionary();
foreach (var childOptionSetting in ChildOptionSettings)
{
var childValue = childOptionSetting.GetValue(replacementTokens);
if (
displayableOptionSettings != null &&
displayableOptionSettings.TryGetValue(childOptionSetting.Id, out bool isDisplayable))
{
if (!isDisplayable)
continue;
}
objectValue[childOptionSetting.Id] = childValue;
}
return objectValue;
}
if (DefaultValue == null)
{
return string.Empty;
}
if (DefaultValue is string defaultValueString)
{
return ApplyReplacementTokens(replacementTokens, defaultValueString);
}
return DefaultValue;
}
public T? GetDefaultValue(IDictionary replacementTokens)
{
var value = GetDefaultValue(replacementTokens);
if (value == null)
{
return default;
}
return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value));
}
public object? GetDefaultValue(IDictionary replacementTokens)
{
if (DefaultValue == null)
{
return null;
}
if (DefaultValue is string defaultValueString)
{
return ApplyReplacementTokens(replacementTokens, defaultValueString);
}
return DefaultValue;
}
///
/// Assigns a value to the OptionSettingItem.
///
/// Value to assign
/// Current deployment recommendation, may be used if the validator needs to consider properties other than itself
///
/// Thrown if one or more determine
/// is not valid.
///
public async Task SetValue(IOptionSettingHandler optionSettingHandler, object valueOverride, IOptionSettingItemValidator[] validators, Recommendation recommendation, bool skipValidation)
{
if (!skipValidation)
{
foreach (var validator in validators)
{
var result = await validator.Validate(valueOverride, recommendation, this);
if (!result.IsValid)
{
Validation.ValidationStatus = ValidationStatus.Invalid;
Validation.ValidationMessage = result.ValidationFailedMessage?.Trim() ?? $"The value '{valueOverride}' is invalid for option setting '{Name}'.";
Validation.InvalidValue = valueOverride;
throw new ValidationFailedException(DeployToolErrorCode.OptionSettingItemValueValidationFailed, Validation.ValidationMessage);
}
}
}
if (AllowedValues != null && AllowedValues.Count > 0 && valueOverride != null &&
!AllowedValues.Contains(valueOverride.ToString() ?? ""))
{
Validation.ValidationStatus = ValidationStatus.Invalid;
Validation.ValidationMessage = $"Invalid value for option setting item '{Name}'";
Validation.InvalidValue = valueOverride;
throw new InvalidOverrideValueException(DeployToolErrorCode.InvalidValueForOptionSettingItem, Validation.ValidationMessage);
}
Validation.ValidationStatus = ValidationStatus.Valid;
Validation.ValidationMessage = string.Empty;
Validation.InvalidValue = null;
try
{
if (valueOverride is bool || valueOverride is int || valueOverride is long || valueOverride is double || valueOverride is Dictionary || valueOverride is SortedSet)
{
_value = valueOverride;
}
else if (Type.Equals(OptionSettingValueType.KeyValue))
{
var deserialized = JsonConvert.DeserializeObject>(valueOverride?.ToString() ?? "");
_value = deserialized;
}
else if (Type.Equals(OptionSettingValueType.List))
{
var deserialized = JsonConvert.DeserializeObject>(valueOverride?.ToString() ?? "");
_value = deserialized;
}
else if (valueOverride is string valueOverrideString)
{
if (bool.TryParse(valueOverrideString, out var valueOverrideBool))
{
_value = valueOverrideBool;
}
else if (int.TryParse(valueOverrideString, out var valueOverrideInt))
{
_value = valueOverrideInt;
}
else
{
_value = valueOverrideString;
}
}
else
{
var deserialized = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(valueOverride));
foreach (var childOptionSetting in ChildOptionSettings)
{
if (deserialized?.TryGetValue(childOptionSetting.Id, out var childValueOverride) ?? false)
{
await optionSettingHandler.SetOptionSettingValue(recommendation, childOptionSetting, childValueOverride, skipValidation: skipValidation);
}
}
}
}
catch (JsonReaderException ex)
{
Validation.ValidationStatus = ValidationStatus.Invalid;
Validation.ValidationMessage = $"The value you are trying to set is invalid.";
Validation.InvalidValue = valueOverride;
throw new UnsupportedOptionSettingType(DeployToolErrorCode.UnsupportedOptionSettingType,
$"The value you are trying to set for the option setting '{Name}' is invalid.",
ex);
}
}
private object ApplyReplacementTokens(IDictionary replacementTokens, object defaultValue)
{
var defaultValueString = defaultValue?.ToString();
if (!string.IsNullOrEmpty(defaultValueString))
{
if (Type != OptionSettingValueType.String)
{
foreach (var token in replacementTokens)
{
if (defaultValueString.Equals(token.Key))
defaultValue = token.Value;
}
}
else
{
foreach (var token in replacementTokens)
{
defaultValueString = defaultValueString.Replace(token.Key, token.Value.ToString());
}
defaultValue = defaultValueString;
}
}
return defaultValue ?? string.Empty;
}
}
}