private static JObject FindPatchTarget(IPolicyPatch policyPatch, JArray policySet)
 {
     return(policySet
            .Children <JObject>()
            .SingleOrDefault(policy => policyPatch
                             .Match
                             .Properties()
                             .Where(p => !p.Name.StartsWith("§"))
                             .All(prop => JToken.DeepEquals(policy.Property(prop.Name), prop))));
 }
        private void ApplyPatch(ILogMessageSink logger, IPolicyPatch patch, JArray policySet)
        {
            List <JObject> patchPolicies = patch.GetPolicies().ToList();

            if (patch.OverrideDeltaMode == OverrideDeltaMode.Replace)
            {
                ApplyReplacePatch(logger, patch, patchPolicies, policySet);
            }
            else if (patch.OverrideDeltaMode == OverrideDeltaMode.AssignProperties)
            {
                ApplyAssignPatch(logger, patch, patchPolicies, policySet);
            }
        }
        private void ApplyAssignPatch(ILogMessageSink logger, IPolicyPatch policyPatch, List <JObject> patchPolicies, JArray policySet)
        {
            foreach (JObject patchPolicy in patchPolicies)
            {
                JObject patchTarget = FindPatchTarget(policyPatch, policySet);

                string sourceTerm = CreateSourceTerm(patchPolicy, policyPatch.PatchSourcePath, "Assign");

                if (patchTarget == null)
                {
                    logger.Warning(
                        $"Patch {sourceTerm} was not applied because a matching base patch was not found.");
                    continue;
                }

                if (policyPatch.PatchTargetQuery != null)
                {
                    patchTarget = (JObject)patchTarget.SelectToken(policyPatch.PatchTargetQuery);

                    if (patchTarget == null)
                    {
                        logger.Warning(
                            $"Patch {sourceTerm} was not applied because a matching base patch target {policyPatch.PatchTargetQuery} was not found.");
                        continue;
                    }
                }

                foreach (JProperty patchProperty in patchPolicy.Properties())
                {
                    if (patchProperty.Name.StartsWith("§"))
                    {
                        continue;
                    }

                    patchTarget[patchProperty.Name] = patchProperty.Value;
                }

                AppendPatchSource(patchTarget, sourceTerm);

                logger.Message($"{sourceTerm}\n\twhere {JsonConvert.SerializeObject(policyPatch.Conditions)}");
            }
        }
        private void ApplyReplacePatch(ILogMessageSink logger, IPolicyPatch policyPatch, List <JObject> patchPolicies, JArray policySet)
        {
            foreach (JObject patchPolicy in patchPolicies)
            {
                JObject originalObject = FindPatchTarget(policyPatch, policySet);

                string sourceTerm = CreateSourceTerm(patchPolicy, policyPatch.PatchSourcePath, "Replace");

                if (originalObject == null)
                {
                    logger.Warning(
                        $"Patch {sourceTerm} was not applied because a matching base patch was not found.");
                    continue;
                }

                int index = policySet.IndexOf(originalObject);

                policySet.RemoveAt(index);

                policySet.Insert(index, patchPolicy);

                logger.Message($"{sourceTerm}\n\twhere {JsonConvert.SerializeObject(policyPatch.Conditions)}");
            }
        }