/// <summary>
 /// Adds a rule to the Rules data store. This will add it to the rulesList.
 /// </summary>
 /// <param name="newRule">The RuleWithSettingsMetadata to be added</param>
 public void AddRule(JObject newRule)
 {
     m_DataStore.rulesList.Add(newRule);
     RulesDataStoreChanged?.Invoke();
     RemoteSettingDataStoreChanged?.Invoke();
     AddRuleToAddedRuleIDs(newRule);
 }
 /// <summary>
 /// Deletes a rule from the Rules data store. This will delete it from the rulesList.
 /// </summary>
 /// <param name="deletedRuleID">ID of the Rule to be deleted</param>
 public void DeleteRule(string deletedRuleID)
 {
     AddRuleToDeletedRuleIDs(GetRuleByID(deletedRuleID));
     m_DataStore.rulesList.Remove(m_DataStore.rulesList.Find(rule => rule.id == deletedRuleID));
     RulesDataStoreChanged?.Invoke();
     RemoteSettingDataStoreChanged?.Invoke();
 }
 /// <summary>
 /// Adds a rule to the Rules data store. This will add it to the rulesList.
 /// </summary>
 /// <param name="newRule">The RuleWithSettingsMetadata to be added</param>
 public void AddRule(RuleWithSettingsMetadata newRule)
 {
     m_DataStore.rulesList.Add(newRule);
     RulesDataStoreChanged?.Invoke();
     RemoteSettingDataStoreChanged?.Invoke();
     AddRuleToAddedRuleIDs(newRule);
 }
        /// <summary>
        /// Sets the Rules data store using a list of Rules.
        /// </summary>
        /// <param name="newRulesDataStore">A list of Rule objects</param>
        public void SetRulesDataStore(List <Rule> newRulesDataStore)
        {
            m_DataStore.rulesList = new List <RuleWithSettingsMetadata>();
            var defaultSettings = m_DataStore.rsKeyList;

            foreach (var rule in newRulesDataStore)
            {
                var settingsInRule = new List <RsKvtData>();
                foreach (var setting in rule.value)
                {
                    string entityId            = null;
                    var    defaultSettingIndex = defaultSettings.FindIndex(item => (item.rs.key == setting.key && item.rs.type == setting.type));
                    if (defaultSettingIndex == -1)
                    {
                        entityId = Guid.NewGuid().ToString();
                    }
                    else
                    {
                        entityId = defaultSettings[defaultSettingIndex].metadata.entityId;
                    }
                    settingsInRule.Add(new RsKvtData(entityId, setting));
                }
                m_DataStore.rulesList.Add(new RuleWithSettingsMetadata(rule.id, rule.name, rule.enabled, rule.priority, rule.condition, rule.rolloutPercentage, settingsInRule, rule.startDate, rule.endDate));
            }
            RulesDataStoreChanged?.Invoke();
            RemoteSettingDataStoreChanged?.Invoke();
        }
        /// <summary>
        /// Deletes the given setting to the given Rule.
        /// </summary>
        /// <param name="ruleId">ID of the rule that the setting should be deleted from</param>
        /// <param name="entityId">EntityId of the setting to be deleted from the given rule</param>
        public void DeleteSettingFromRule(string ruleId, string entityId)
        {
            var setting = m_DataStore.rulesList.Find(r => r.id == ruleId).value.Find(x => x.metadata.entityId == entityId);

            m_DataStore.rulesList.Find(r => r.id == ruleId).value.Remove(setting);
            RemoteSettingDataStoreChanged?.Invoke();
            AddRuleToUpdatedRuleIDs(ruleId);
        }
        /// <summary>
        /// Adds the given setting to the given rule.
        /// </summary>
        /// <param name="selectedRuleId">ID of the rule that the setting should be added to</param>
        /// <param name="entityId">EntityId of the setting to be added to the given rule</param>
        public void AddSettingToRule(string selectedRuleId, string entityId)
        {
            var setting = m_DataStore.rsKeyList.Find(s => s.metadata.entityId == entityId);

            m_DataStore.rulesList.Find(r => r.id == selectedRuleId).value.Add(setting);
            RemoteSettingDataStoreChanged?.Invoke();
            AddRuleToUpdatedRuleIDs(selectedRuleId);
        }
        /// <summary>
        /// Updates the value of the given setting for the given rule.
        /// </summary>
        /// <param name="ruleId">ID of the rule that the updated setting belong to</param>
        /// <param name="updatedSetting">A RsKvtData containing the updated value</param>
        public void UpdateSettingForRule(string ruleId, RsKvtData updatedSetting)
        {
            var ruleIndex    = m_DataStore.rulesList.FindIndex(item => item.id == ruleId);
            var rule         = m_DataStore.rulesList[ruleIndex];
            var setting      = rule.value.Find(arg => arg.metadata.entityId == updatedSetting.metadata.entityId);
            var settingIndex = rule.value.IndexOf(setting);

            rule.value[settingIndex]         = updatedSetting;
            m_DataStore.rulesList[ruleIndex] = rule;
            RemoteSettingDataStoreChanged?.Invoke();
            AddRuleToUpdatedRuleIDs(ruleId);
        }
 /// <summary>
 /// Deletes a setting from the Remote Settings data store. This will delete the setting from the rsKeyList.
 /// </summary>
 /// <param name="entityId">The EntityId of the setting to be deleted</param>
 public void DeleteSetting(string entityId)
 {
     for (int i = 0; i < m_DataStore.rsKeyList.Count; i++)
     {
         if (m_DataStore.rsKeyList[i]["metadata"]["entityId"].Value <string>() == entityId)
         {
             m_DataStore.rsKeyList.RemoveAt(i);
             break;
         }
     }
     //m_DataStore.rsKeyList.Remove(m_DataStore.rsKeyList.Find(s => s.metadata.entityId == entityId));
     RemoteSettingDataStoreChanged?.Invoke();
 }
 /// <summary>
 /// Deletes a rule from the Rules data store. This will delete it from the rulesList.
 /// </summary>
 /// <param name="deletedRuleID">ID of the Rule to be deleted</param>
 public void DeleteRule(string deletedRuleID)
 {
     AddRuleToDeletedRuleIDs(deletedRuleID);
     for (int i = 0; i < m_DataStore.rulesList.Count; i++)
     {
         if (m_DataStore.rulesList[i]["id"].Value <string>() == deletedRuleID)
         {
             m_DataStore.rulesList.RemoveAt(i);
             break;
         }
     }
     //m_DataStore.rulesList.Remove(m_DataStore.rulesList.Find(rule => rule.id == deletedRuleID));
     RulesDataStoreChanged?.Invoke();
     RemoteSettingDataStoreChanged?.Invoke();
 }
        /// <summary>
        /// Updates a setting in the Remote Settings data store. This will update the setting in the rsKeyList.
        /// </summary>
        /// <param name="oldSetting">The RsKvtData of the setting to be updated</param>
        /// <param name="newSetting">The new setting with the updated fields</param>
        public void UpdateSetting(RsKvtData oldSetting, RsKvtData newSetting)
        {
            var isError = false;

            if (newSetting.rs.key.Length >= 255)
            {
                Debug.LogWarning(newSetting.rs.key + " is at the maximum length of 255 characters.");
                isError = true;
            }
            if (!isError)
            {
                var settingIndex = m_DataStore.rsKeyList.IndexOf(oldSetting);
                m_DataStore.rsKeyList[settingIndex] = newSetting;
                OnRemoteSettingUpdated(oldSetting.rs.key, newSetting);
                RemoteSettingDataStoreChanged?.Invoke();
            }
        }
 /// <summary>
 /// Updates the value of the given setting for the given rule.
 /// </summary>
 /// <param name="ruleId">ID of the rule that the updated setting belong to</param>
 /// <param name="updatedSetting">A RsKvtData containing the updated value</param>
 public void UpdateSettingForRule(string ruleId, JObject updatedSetting)
 {
     for (int i = 0; i < m_DataStore.rulesList.Count; i++)
     {
         if (m_DataStore.rulesList[i]["id"].Value <string>() == ruleId)
         {
             var tempArr = (JArray)m_DataStore.rulesList[i]["value"];
             for (int j = 0; j < tempArr.Count; j++)
             {
                 if (tempArr[j]["metadata"]["entityId"].Value <string>() == updatedSetting["metadata"]["entityId"].Value <string>())
                 {
                     tempArr[j] = updatedSetting;
                 }
             }
         }
     }
     RemoteSettingDataStoreChanged?.Invoke();
     AddRuleToUpdatedRuleIDs(ruleId);
 }
        /// <summary>
        /// Updates a setting in the Remote Settings data store. This will update the setting in the rsKeyList.
        /// </summary>
        /// <param name="oldSetting">The RsKvtData of the setting to be updated</param>
        /// <param name="newSetting">The new setting with the updated fields</param>
        public void UpdateSetting(JObject oldSetting, JObject newSetting)
        {
            var isError = false;

            if (newSetting["rs"]["key"].Value <string>().Length >= 255)
            {
                Debug.LogWarning(newSetting["rs"]["key"].Value <string>() + " is at the maximum length of 255 characters.");
                isError = true;
            }
            if (!isError)
            {
                for (int i = 0; i < m_DataStore.rsKeyList.Count; i++)
                {
                    if (m_DataStore.rsKeyList[i]["metadata"]["entityId"].Value <string>() == oldSetting["metadata"]["entityId"].Value <string>())
                    {
                        m_DataStore.rsKeyList[i] = newSetting;
                    }
                }
                RemoteSettingDataStoreChanged?.Invoke();
            }
        }
        /// <summary>
        /// Adds the given setting to the given rule.
        /// </summary>
        /// <param name="selectedRuleId">ID of the rule that the setting should be added to</param>
        /// <param name="entityId">EntityId of the setting to be added to the given rule</param>
        public void AddSettingToRule(string selectedRuleId, string entityId)
        {
            if (IsSettingInRule(selectedRuleId, entityId))
            {
                return;
            }

            for (int i = 0; i < m_DataStore.rulesList.Count; i++)
            {
                if (m_DataStore.rulesList[i]["id"].Value <string>() == selectedRuleId)
                {
                    var currentRuleSettings = (JArray)m_DataStore.rulesList[i]["value"];
                    for (int j = 0; j < m_DataStore.rsKeyList.Count; j++)
                    {
                        if (m_DataStore.rsKeyList[j]["metadata"]["entityId"].Value <string>() == entityId)
                        {
                            currentRuleSettings.Add(m_DataStore.rsKeyList[j]);
                        }
                    }
                }
            }
            RemoteSettingDataStoreChanged?.Invoke();
            AddRuleToUpdatedRuleIDs(selectedRuleId);
        }
        /// <summary>
        /// Deletes the given setting to the given Rule.
        /// </summary>
        /// <param name="ruleId">ID of the rule that the setting should be deleted from</param>
        /// <param name="entityId">EntityId of the setting to be deleted from the given rule</param>
        public void DeleteSettingFromRule(string ruleId, string entityId)
        {
            if (!IsSettingInRule(ruleId, entityId))
            {
                return;
            }

            for (int i = 0; i < m_DataStore.rulesList.Count; i++)
            {
                if (m_DataStore.rulesList[i]["id"].Value <string>() == ruleId)
                {
                    var currentRuleSettings = (JArray)m_DataStore.rulesList[i]["value"];
                    for (int j = 0; j < currentRuleSettings.Count; j++)
                    {
                        if (currentRuleSettings[j]["metadata"]["entityId"].Value <string>() == entityId)
                        {
                            currentRuleSettings.Remove(currentRuleSettings[j]);
                        }
                    }
                }
            }
            RemoteSettingDataStoreChanged?.Invoke();
            AddRuleToUpdatedRuleIDs(ruleId);
        }
        /// <summary>
        /// Sets the Rules data store using a list of Rules.
        /// </summary>
        /// <param name="newRulesDataStore">A list of Rule objects</param>
        public void SetRulesDataStore(JArray newRulesDataStore)
        {
            m_DataStore.rulesList = new JArray();
            var defaultSettings = m_DataStore.rsKeyList;

            foreach (var rule in newRulesDataStore)
            {
                if (rule["type"].Value <string>() == "segmentation")
                {
                    var settingsInRule = new JArray();
                    foreach (var setting in rule["value"])
                    {
                        var newSetting = new JObject();

                        // if rule is already formatted, with ["rs"] key present in the setting, leave setting as is:
                        if (setting["rs"] != null)
                        {
                            newSetting = (JObject)setting;
                        }
                        else
                        {
                            string entityId            = null;
                            var    defaultSettingIndex = -1;
                            for (int i = 0; i < defaultSettings.Count; i++)
                            {
                                if (defaultSettings[i]["rs"]["key"].Value <string>() == setting["key"].Value <string>() && defaultSettings[i]["rs"]["type"].Value <string>() == setting["type"].Value <string>())
                                {
                                    defaultSettingIndex = i;
                                }
                            }
                            if (defaultSettingIndex == -1)
                            {
                                entityId = Guid.NewGuid().ToString();
                            }
                            else
                            {
                                entityId = defaultSettings[defaultSettingIndex]["metadata"]["entityId"].Value <string>();
                            }

                            newSetting["metadata"]             = new JObject();
                            newSetting["metadata"]["entityId"] = entityId;
                            newSetting["rs"] = setting;
                        }

                        settingsInRule.Add(newSetting);
                    }
                    var newRule = rule;
                    newRule["value"] = settingsInRule;
                    m_DataStore.rulesList.Add(newRule);
                }
                else if (rule["type"].Value <string>() == "variant")
                {
                    foreach (var variant in rule["value"])
                    {
                        var variantsJArray    = (JArray)variant["values"];
                        var settingsInVariant = new JArray();
                        for (int i = 0; i < variantsJArray.Count; i++)
                        {
                            var newSetting = new JObject();

                            // if rule is already formatted, with ["rs"] key present in the setting, leave setting as is:
                            if (variantsJArray[i]["rs"] != null)
                            {
                                newSetting = (JObject)variantsJArray[i];
                            }
                            else
                            {
                                string entityId            = null;
                                var    defaultSettingIndex = -1;
                                for (int j = 0; j < defaultSettings.Count; j++)
                                {
                                    if (defaultSettings[j]["rs"]["key"].Value <string>() == variantsJArray[i]["key"].Value <string>() && defaultSettings[j]["rs"]["type"].Value <string>() == variantsJArray[i]["type"].Value <string>())
                                    {
                                        defaultSettingIndex = j;
                                    }
                                }
                                if (defaultSettingIndex == -1)
                                {
                                    entityId = Guid.NewGuid().ToString();
                                }
                                else
                                {
                                    entityId = defaultSettings[defaultSettingIndex]["metadata"]["entityId"].Value <string>();
                                }

                                newSetting["metadata"]             = new JObject();
                                newSetting["metadata"]["entityId"] = entityId;
                                newSetting["rs"] = variantsJArray[i];
                            }

                            settingsInVariant.Add(newSetting);
                        }
                        variant["values"] = settingsInVariant;
                    }
                    m_DataStore.rulesList.Add(rule);
                }
            }
            RulesDataStoreChanged?.Invoke();
            RemoteSettingDataStoreChanged?.Invoke();
        }
 /// <summary>
 /// Deletes a setting from the Remote Settings data store. This will delete the setting from the rsKeyList.
 /// </summary>
 /// <param name="entityId">The EntityId of the setting to be deleted</param>
 public void DeleteSetting(string entityId)
 {
     m_DataStore.rsKeyList.Remove(m_DataStore.rsKeyList.Find(s => s.metadata.entityId == entityId));
     RemoteSettingDataStoreChanged?.Invoke();
 }
 /// <summary>
 /// Adds a setting to the Remote Settings data store. This will add the setting to the rsKeyList.
 /// </summary>
 /// <param name="newSetting">The setting to be added</param>
 public void AddSetting(JObject newSetting)
 {
     m_DataStore.rsKeyList.Add(newSetting);
     RemoteSettingDataStoreChanged?.Invoke();
 }