// Copyright (C) 2020 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "src/metrics/parsing_utils/config_update_utils.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <private/android_filesystem_config.h>
#include <stdio.h>

#include <set>
#include <unordered_map>
#include <vector>

#include "packages/modules/StatsD/bin/src/statsd_config.pb.h"
#include "src/condition/CombinationConditionTracker.h"
#include "src/condition/SimpleConditionTracker.h"
#include "src/matchers/CombinationAtomMatchingTracker.h"
#include "src/metrics/DurationMetricProducer.h"
#include "src/metrics/GaugeMetricProducer.h"
#include "src/metrics/ValueMetricProducer.h"
#include "src/metrics/parsing_utils/metrics_manager_util.h"
#include "tests/statsd_test_util.h"

using namespace testing;
using android::sp;
using android::os::statsd::Predicate;
using std::map;
using std::nullopt;
using std::optional;
using std::set;
using std::unordered_map;
using std::vector;

#ifdef __ANDROID__

namespace android {
namespace os {
namespace statsd {

namespace {

ConfigKey key(123, 456);
const int64_t timeBaseNs = 1000 * NS_PER_SEC;

sp<UidMap> uidMap = new UidMap();
sp<StatsPullerManager> pullerManager = new StatsPullerManager();
sp<AlarmMonitor> anomalyAlarmMonitor;
sp<AlarmMonitor> periodicAlarmMonitor = new AlarmMonitor(
        /*minDiffToUpdateRegisteredAlarmTimeSec=*/0,
        [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
        [](const shared_ptr<IStatsCompanionService>&) {});
set<int> allTagIds;
vector<sp<AtomMatchingTracker>> oldAtomMatchingTrackers;
unordered_map<int64_t, int> oldAtomMatchingTrackerMap;
vector<sp<ConditionTracker>> oldConditionTrackers;
unordered_map<int64_t, int> oldConditionTrackerMap;
vector<sp<MetricProducer>> oldMetricProducers;
unordered_map<int64_t, int> oldMetricProducerMap;
std::vector<sp<AnomalyTracker>> oldAnomalyTrackers;
unordered_map<int64_t, int> oldAlertTrackerMap;
std::vector<sp<AlarmTracker>> oldAlarmTrackers;
unordered_map<int, std::vector<int>> tmpConditionToMetricMap;
unordered_map<int, std::vector<int>> tmpTrackerToMetricMap;
unordered_map<int, std::vector<int>> tmpTrackerToConditionMap;
unordered_map<int, std::vector<int>> tmpActivationAtomTrackerToMetricMap;
unordered_map<int, std::vector<int>> tmpDeactivationAtomTrackerToMetricMap;
vector<int> metricsWithActivation;
map<int64_t, uint64_t> oldStateHashes;
std::set<int64_t> noReportMetricIds;

class ConfigUpdateTest : public ::testing::Test {
public:
    ConfigUpdateTest() {
    }

    void SetUp() override {
        allTagIds.clear();
        oldAtomMatchingTrackers.clear();
        oldAtomMatchingTrackerMap.clear();
        oldConditionTrackers.clear();
        oldConditionTrackerMap.clear();
        oldMetricProducers.clear();
        oldMetricProducerMap.clear();
        oldAnomalyTrackers.clear();
        oldAlarmTrackers.clear();
        tmpConditionToMetricMap.clear();
        tmpTrackerToMetricMap.clear();
        tmpTrackerToConditionMap.clear();
        tmpActivationAtomTrackerToMetricMap.clear();
        tmpDeactivationAtomTrackerToMetricMap.clear();
        oldAlertTrackerMap.clear();
        metricsWithActivation.clear();
        oldStateHashes.clear();
        noReportMetricIds.clear();
        StateManager::getInstance().clear();
    }
};

bool initConfig(const StatsdConfig& config) {
    return initStatsdConfig(
            key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
            timeBaseNs, timeBaseNs, allTagIds, oldAtomMatchingTrackers, oldAtomMatchingTrackerMap,
            oldConditionTrackers, oldConditionTrackerMap, oldMetricProducers, oldMetricProducerMap,
            oldAnomalyTrackers, oldAlarmTrackers, tmpConditionToMetricMap, tmpTrackerToMetricMap,
            tmpTrackerToConditionMap, tmpActivationAtomTrackerToMetricMap,
            tmpDeactivationAtomTrackerToMetricMap, oldAlertTrackerMap, metricsWithActivation,
            oldStateHashes, noReportMetricIds);
}

EventMetric createEventMetric(string name, int64_t what, optional<int64_t> condition) {
    EventMetric metric;
    metric.set_id(StringToId(name));
    metric.set_what(what);
    if (condition) {
        metric.set_condition(condition.value());
    }
    return metric;
}

DurationMetric createDurationMetric(string name, int64_t what, optional<int64_t> condition,
                                    vector<int64_t> states) {
    DurationMetric metric;
    metric.set_id(StringToId(name));
    metric.set_what(what);
    metric.set_bucket(TEN_MINUTES);
    if (condition) {
        metric.set_condition(condition.value());
    }
    for (const int64_t state : states) {
        metric.add_slice_by_state(state);
    }
    return metric;
}

ValueMetric createValueMetric(string name, const AtomMatcher& what, optional<int64_t> condition,
                              vector<int64_t> states) {
    ValueMetric metric;
    metric.set_id(StringToId(name));
    metric.set_what(what.id());
    metric.set_bucket(TEN_MINUTES);
    metric.mutable_value_field()->set_field(what.simple_atom_matcher().atom_id());
    metric.mutable_value_field()->add_child()->set_field(2);
    if (condition) {
        metric.set_condition(condition.value());
    }
    for (const int64_t state : states) {
        metric.add_slice_by_state(state);
    }
    return metric;
}

Alert createAlert(string name, int64_t metricId, int buckets, int64_t triggerSum) {
    Alert alert;
    alert.set_id(StringToId(name));
    alert.set_metric_id(metricId);
    alert.set_num_buckets(buckets);
    alert.set_trigger_if_sum_gt(triggerSum);
    return alert;
}

Subscription createSubscription(string name, Subscription_RuleType type, int64_t ruleId) {
    Subscription subscription;
    subscription.set_id(StringToId(name));
    subscription.set_rule_type(type);
    subscription.set_rule_id(ruleId);
    subscription.mutable_broadcast_subscriber_details();
    return subscription;
}

Alarm createAlarm(string name, int64_t offsetMillis, int64_t periodMillis) {
    Alarm alarm;
    alarm.set_id(StringToId(name));
    alarm.set_offset_millis(offsetMillis);
    alarm.set_period_millis(periodMillis);
    return alarm;
}
}  // anonymous namespace

TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) {
    StatsdConfig config;
    AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
    int64_t matcherId = matcher.id();
    *config.add_atom_matcher() = matcher;

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(1, false);
    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    newAtomMatchingTrackerMap[matcherId] = 0;
    EXPECT_TRUE(determineMatcherUpdateStatus(config, 0, oldAtomMatchingTrackerMap,
                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                             matchersToUpdate, cycleTracker));
    EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestSimpleMatcherReplace) {
    StatsdConfig config;
    AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
    *config.add_atom_matcher() = matcher;

    EXPECT_TRUE(initConfig(config));

    StatsdConfig newConfig;
    // Same id, different atom, so should be replaced.
    AtomMatcher newMatcher = CreateSimpleAtomMatcher("TEST", /*atom=*/11);
    int64_t matcherId = newMatcher.id();
    EXPECT_EQ(matcherId, matcher.id());
    *newConfig.add_atom_matcher() = newMatcher;

    vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(1, false);
    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    newAtomMatchingTrackerMap[matcherId] = 0;
    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                             matchersToUpdate, cycleTracker));
    EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestSimpleMatcherNew) {
    StatsdConfig config;
    AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
    *config.add_atom_matcher() = matcher;

    EXPECT_TRUE(initConfig(config));

    StatsdConfig newConfig;
    // Different id, so should be a new matcher.
    AtomMatcher newMatcher = CreateSimpleAtomMatcher("DIFFERENT_NAME", /*atom=*/10);
    int64_t matcherId = newMatcher.id();
    EXPECT_NE(matcherId, matcher.id());
    *newConfig.add_atom_matcher() = newMatcher;

    vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(1, false);
    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    newAtomMatchingTrackerMap[matcherId] = 0;
    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                             matchersToUpdate, cycleTracker));
    EXPECT_EQ(matchersToUpdate[0], UPDATE_NEW);
}

TEST_F(ConfigUpdateTest, TestCombinationMatcherPreserve) {
    StatsdConfig config;
    AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
    *config.add_atom_matcher() = matcher2;
    int64_t matcher2Id = matcher2.id();

    AtomMatcher matcher3;
    matcher3.set_id(StringToId("TEST3"));
    AtomMatcher_Combination* combination = matcher3.mutable_combination();
    combination->set_operation(LogicalOperation::OR);
    combination->add_matcher(matcher1Id);
    combination->add_matcher(matcher2Id);
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    EXPECT_TRUE(initConfig(config));

    StatsdConfig newConfig;
    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    // Same matchers, different order, all should be preserved.
    *newConfig.add_atom_matcher() = matcher2;
    newAtomMatchingTrackerMap[matcher2Id] = 0;
    *newConfig.add_atom_matcher() = matcher3;
    newAtomMatchingTrackerMap[matcher3Id] = 1;
    *newConfig.add_atom_matcher() = matcher1;
    newAtomMatchingTrackerMap[matcher1Id] = 2;

    vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(3, false);
    // Only update the combination. It should recurse the two child matchers and preserve all 3.
    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                             matchersToUpdate, cycleTracker));
    EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
    EXPECT_EQ(matchersToUpdate[1], UPDATE_PRESERVE);
    EXPECT_EQ(matchersToUpdate[2], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestCombinationMatcherReplace) {
    StatsdConfig config;
    AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
    *config.add_atom_matcher() = matcher2;
    int64_t matcher2Id = matcher2.id();

    AtomMatcher matcher3;
    matcher3.set_id(StringToId("TEST3"));
    AtomMatcher_Combination* combination = matcher3.mutable_combination();
    combination->set_operation(LogicalOperation::OR);
    combination->add_matcher(matcher1Id);
    combination->add_matcher(matcher2Id);
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    EXPECT_TRUE(initConfig(config));

    // Change the logical operation of the combination matcher, causing a replacement.
    matcher3.mutable_combination()->set_operation(LogicalOperation::AND);

    StatsdConfig newConfig;
    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    *newConfig.add_atom_matcher() = matcher2;
    newAtomMatchingTrackerMap[matcher2Id] = 0;
    *newConfig.add_atom_matcher() = matcher3;
    newAtomMatchingTrackerMap[matcher3Id] = 1;
    *newConfig.add_atom_matcher() = matcher1;
    newAtomMatchingTrackerMap[matcher1Id] = 2;

    vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(3, false);
    // Only update the combination. The simple matchers should not be evaluated.
    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                             matchersToUpdate, cycleTracker));
    EXPECT_EQ(matchersToUpdate[0], UPDATE_UNKNOWN);
    EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
    EXPECT_EQ(matchersToUpdate[2], UPDATE_UNKNOWN);
}

TEST_F(ConfigUpdateTest, TestCombinationMatcherDepsChange) {
    StatsdConfig config;
    AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
    *config.add_atom_matcher() = matcher2;
    int64_t matcher2Id = matcher2.id();

    AtomMatcher matcher3;
    matcher3.set_id(StringToId("TEST3"));
    AtomMatcher_Combination* combination = matcher3.mutable_combination();
    combination->set_operation(LogicalOperation::OR);
    combination->add_matcher(matcher1Id);
    combination->add_matcher(matcher2Id);
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    EXPECT_TRUE(initConfig(config));

    // Change a dependency of matcher 3.
    matcher2.mutable_simple_atom_matcher()->set_atom_id(12);

    StatsdConfig newConfig;
    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    *newConfig.add_atom_matcher() = matcher2;
    newAtomMatchingTrackerMap[matcher2Id] = 0;
    *newConfig.add_atom_matcher() = matcher3;
    newAtomMatchingTrackerMap[matcher3Id] = 1;
    *newConfig.add_atom_matcher() = matcher1;
    newAtomMatchingTrackerMap[matcher1Id] = 2;

    vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(3, false);
    // Only update the combination.
    EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
                                             oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                             matchersToUpdate, cycleTracker));
    // Matcher 2 and matcher3 must be reevaluated. Matcher 1 might, but does not need to be.
    EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
    EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestUpdateMatchers) {
    StatsdConfig config;
    // Will be preserved.
    AtomMatcher simple1 = CreateSimpleAtomMatcher("SIMPLE1", /*atom=*/10);
    int64_t simple1Id = simple1.id();
    *config.add_atom_matcher() = simple1;

    // Will be replaced.
    AtomMatcher simple2 = CreateSimpleAtomMatcher("SIMPLE2", /*atom=*/11);
    *config.add_atom_matcher() = simple2;
    int64_t simple2Id = simple2.id();

    // Will be removed.
    AtomMatcher simple3 = CreateSimpleAtomMatcher("SIMPLE3", /*atom=*/12);
    *config.add_atom_matcher() = simple3;
    int64_t simple3Id = simple3.id();

    // Will be preserved.
    AtomMatcher combination1;
    combination1.set_id(StringToId("combination1"));
    AtomMatcher_Combination* combination = combination1.mutable_combination();
    combination->set_operation(LogicalOperation::NOT);
    combination->add_matcher(simple1Id);
    int64_t combination1Id = combination1.id();
    *config.add_atom_matcher() = combination1;

    // Will be replaced since it depends on simple2.
    AtomMatcher combination2;
    combination2.set_id(StringToId("combination2"));
    combination = combination2.mutable_combination();
    combination->set_operation(LogicalOperation::AND);
    combination->add_matcher(simple1Id);
    combination->add_matcher(simple2Id);
    int64_t combination2Id = combination2.id();
    *config.add_atom_matcher() = combination2;

    EXPECT_TRUE(initConfig(config));

    // Change simple2, causing simple2 and combination2 to be replaced.
    simple2.mutable_simple_atom_matcher()->set_atom_id(111);

    // 2 new matchers: simple4 and combination3:
    AtomMatcher simple4 = CreateSimpleAtomMatcher("SIMPLE4", /*atom=*/13);
    int64_t simple4Id = simple4.id();

    AtomMatcher combination3;
    combination3.set_id(StringToId("combination3"));
    combination = combination3.mutable_combination();
    combination->set_operation(LogicalOperation::AND);
    combination->add_matcher(simple4Id);
    combination->add_matcher(simple2Id);
    int64_t combination3Id = combination3.id();

    StatsdConfig newConfig;
    *newConfig.add_atom_matcher() = combination3;
    *newConfig.add_atom_matcher() = simple2;
    *newConfig.add_atom_matcher() = combination2;
    *newConfig.add_atom_matcher() = simple1;
    *newConfig.add_atom_matcher() = simple4;
    *newConfig.add_atom_matcher() = combination1;

    set<int> newTagIds;
    unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
    set<int64_t> replacedMatchers;
    EXPECT_TRUE(updateAtomMatchingTrackers(
            newConfig, uidMap, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers, newTagIds,
            newAtomMatchingTrackerMap, newAtomMatchingTrackers, replacedMatchers));

    ASSERT_EQ(newTagIds.size(), 3);
    EXPECT_EQ(newTagIds.count(10), 1);
    EXPECT_EQ(newTagIds.count(111), 1);
    EXPECT_EQ(newTagIds.count(13), 1);

    ASSERT_EQ(newAtomMatchingTrackerMap.size(), 6);
    EXPECT_EQ(newAtomMatchingTrackerMap.at(combination3Id), 0);
    EXPECT_EQ(newAtomMatchingTrackerMap.at(simple2Id), 1);
    EXPECT_EQ(newAtomMatchingTrackerMap.at(combination2Id), 2);
    EXPECT_EQ(newAtomMatchingTrackerMap.at(simple1Id), 3);
    EXPECT_EQ(newAtomMatchingTrackerMap.at(simple4Id), 4);
    EXPECT_EQ(newAtomMatchingTrackerMap.at(combination1Id), 5);

    ASSERT_EQ(newAtomMatchingTrackers.size(), 6);
    // Make sure all atom matchers are initialized:
    for (const sp<AtomMatchingTracker>& tracker : newAtomMatchingTrackers) {
        EXPECT_TRUE(tracker->mInitialized);
    }
    // Make sure preserved atom matchers are the same.
    EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple1Id)],
              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple1Id)]);
    EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination1Id)],
              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination1Id)]);
    // Make sure replaced matchers are different.
    EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple2Id)],
              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple2Id)]);
    EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination2Id)],
              newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination2Id)]);

    // Validation, make sure the matchers have the proper ids/indices. Could do more checks here.
    EXPECT_EQ(newAtomMatchingTrackers[0]->getId(), combination3Id);
    EXPECT_EQ(newAtomMatchingTrackers[0]->mIndex, 0);
    EXPECT_EQ(newAtomMatchingTrackers[1]->getId(), simple2Id);
    EXPECT_EQ(newAtomMatchingTrackers[1]->mIndex, 1);
    EXPECT_EQ(newAtomMatchingTrackers[2]->getId(), combination2Id);
    EXPECT_EQ(newAtomMatchingTrackers[2]->mIndex, 2);
    EXPECT_EQ(newAtomMatchingTrackers[3]->getId(), simple1Id);
    EXPECT_EQ(newAtomMatchingTrackers[3]->mIndex, 3);
    EXPECT_EQ(newAtomMatchingTrackers[4]->getId(), simple4Id);
    EXPECT_EQ(newAtomMatchingTrackers[4]->mIndex, 4);
    EXPECT_EQ(newAtomMatchingTrackers[5]->getId(), combination1Id);
    EXPECT_EQ(newAtomMatchingTrackers[5]->mIndex, 5);

    // Verify child indices of Combination Matchers are correct.
    CombinationAtomMatchingTracker* combinationTracker1 =
            static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[5].get());
    vector<int>* childMatchers = &combinationTracker1->mChildren;
    EXPECT_EQ(childMatchers->size(), 1);
    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());

    CombinationAtomMatchingTracker* combinationTracker2 =
            static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[2].get());
    childMatchers = &combinationTracker2->mChildren;
    EXPECT_EQ(childMatchers->size(), 2);
    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());

    CombinationAtomMatchingTracker* combinationTracker3 =
            static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[0].get());
    childMatchers = &combinationTracker3->mChildren;
    EXPECT_EQ(childMatchers->size(), 2);
    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
    EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 4), childMatchers->end());

    // Expect replacedMatchers to have simple2 and combination2
    ASSERT_EQ(replacedMatchers.size(), 2);
    EXPECT_NE(replacedMatchers.find(simple2Id), replacedMatchers.end());
    EXPECT_NE(replacedMatchers.find(combination2Id), replacedMatchers.end());
}

TEST_F(ConfigUpdateTest, TestSimpleConditionPreserve) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    set<int64_t> replacedMatchers;
    vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(1, false);
    unordered_map<int64_t, int> newConditionTrackerMap;
    newConditionTrackerMap[predicate.id()] = 0;
    EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
                                               oldConditionTrackers, newConditionTrackerMap,
                                               replacedMatchers, conditionsToUpdate, cycleTracker));
    EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestSimpleConditionReplace) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    EXPECT_TRUE(initConfig(config));

    // Modify the predicate.
    config.mutable_predicate(0)->mutable_simple_predicate()->set_count_nesting(true);

    set<int64_t> replacedMatchers;
    vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(1, false);
    unordered_map<int64_t, int> newConditionTrackerMap;
    newConditionTrackerMap[predicate.id()] = 0;
    EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
                                               oldConditionTrackers, newConditionTrackerMap,
                                               replacedMatchers, conditionsToUpdate, cycleTracker));
    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestSimpleConditionDepsChange) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    int64_t startMatcherId = startMatcher.id();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    EXPECT_TRUE(initConfig(config));

    // Start matcher was replaced.
    set<int64_t> replacedMatchers;
    replacedMatchers.insert(startMatcherId);

    vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(1, false);
    unordered_map<int64_t, int> newConditionTrackerMap;
    newConditionTrackerMap[predicate.id()] = 0;
    EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
                                               oldConditionTrackers, newConditionTrackerMap,
                                               replacedMatchers, conditionsToUpdate, cycleTracker));
    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestCombinationConditionPreserve) {
    StatsdConfig config;
    AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = screenOnMatcher;
    AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = screenOffMatcher;

    Predicate simple1 = CreateScreenIsOnPredicate();
    *config.add_predicate() = simple1;
    Predicate simple2 = CreateScreenIsOffPredicate();
    *config.add_predicate() = simple2;

    Predicate combination1;
    combination1.set_id(StringToId("COMBINATION1"));
    Predicate_Combination* combinationInternal = combination1.mutable_combination();
    combinationInternal->set_operation(LogicalOperation::NAND);
    combinationInternal->add_predicate(simple1.id());
    combinationInternal->add_predicate(simple2.id());
    *config.add_predicate() = combination1;

    EXPECT_TRUE(initConfig(config));

    // Same predicates, different order
    StatsdConfig newConfig;
    unordered_map<int64_t, int> newConditionTrackerMap;
    *newConfig.add_predicate() = combination1;
    newConditionTrackerMap[combination1.id()] = 0;
    *newConfig.add_predicate() = simple2;
    newConditionTrackerMap[simple2.id()] = 1;
    *newConfig.add_predicate() = simple1;
    newConditionTrackerMap[simple1.id()] = 2;

    set<int64_t> replacedMatchers;
    vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(3, false);
    // Only update the combination. It should recurse the two child predicates and preserve all 3.
    EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
                                               oldConditionTrackers, newConditionTrackerMap,
                                               replacedMatchers, conditionsToUpdate, cycleTracker));
    EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
    EXPECT_EQ(conditionsToUpdate[1], UPDATE_PRESERVE);
    EXPECT_EQ(conditionsToUpdate[2], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestCombinationConditionReplace) {
    StatsdConfig config;
    AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = screenOnMatcher;
    AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = screenOffMatcher;

    Predicate simple1 = CreateScreenIsOnPredicate();
    *config.add_predicate() = simple1;
    Predicate simple2 = CreateScreenIsOffPredicate();
    *config.add_predicate() = simple2;

    Predicate combination1;
    combination1.set_id(StringToId("COMBINATION1"));
    Predicate_Combination* combinationInternal = combination1.mutable_combination();
    combinationInternal->set_operation(LogicalOperation::NAND);
    combinationInternal->add_predicate(simple1.id());
    combinationInternal->add_predicate(simple2.id());
    *config.add_predicate() = combination1;

    EXPECT_TRUE(initConfig(config));

    // Changing the logical operation changes the predicate definition, so it should be replaced.
    combination1.mutable_combination()->set_operation(LogicalOperation::OR);

    StatsdConfig newConfig;
    unordered_map<int64_t, int> newConditionTrackerMap;
    *newConfig.add_predicate() = combination1;
    newConditionTrackerMap[combination1.id()] = 0;
    *newConfig.add_predicate() = simple2;
    newConditionTrackerMap[simple2.id()] = 1;
    *newConfig.add_predicate() = simple1;
    newConditionTrackerMap[simple1.id()] = 2;

    set<int64_t> replacedMatchers;
    vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(3, false);
    // Only update the combination. The simple conditions should not be evaluated.
    EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
                                               oldConditionTrackers, newConditionTrackerMap,
                                               replacedMatchers, conditionsToUpdate, cycleTracker));
    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
    EXPECT_EQ(conditionsToUpdate[1], UPDATE_UNKNOWN);
    EXPECT_EQ(conditionsToUpdate[2], UPDATE_UNKNOWN);
}

TEST_F(ConfigUpdateTest, TestCombinationConditionDepsChange) {
    StatsdConfig config;
    AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = screenOnMatcher;
    AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = screenOffMatcher;

    Predicate simple1 = CreateScreenIsOnPredicate();
    *config.add_predicate() = simple1;
    Predicate simple2 = CreateScreenIsOffPredicate();
    *config.add_predicate() = simple2;

    Predicate combination1;
    combination1.set_id(StringToId("COMBINATION1"));
    Predicate_Combination* combinationInternal = combination1.mutable_combination();
    combinationInternal->set_operation(LogicalOperation::NAND);
    combinationInternal->add_predicate(simple1.id());
    combinationInternal->add_predicate(simple2.id());
    *config.add_predicate() = combination1;

    EXPECT_TRUE(initConfig(config));

    simple2.mutable_simple_predicate()->set_count_nesting(false);

    StatsdConfig newConfig;
    unordered_map<int64_t, int> newConditionTrackerMap;
    *newConfig.add_predicate() = combination1;
    newConditionTrackerMap[combination1.id()] = 0;
    *newConfig.add_predicate() = simple2;
    newConditionTrackerMap[simple2.id()] = 1;
    *newConfig.add_predicate() = simple1;
    newConditionTrackerMap[simple1.id()] = 2;

    set<int64_t> replacedMatchers;
    vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
    vector<bool> cycleTracker(3, false);
    // Only update the combination. Simple2 and combination1 must be evaluated.
    EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
                                               oldConditionTrackers, newConditionTrackerMap,
                                               replacedMatchers, conditionsToUpdate, cycleTracker));
    EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
    EXPECT_EQ(conditionsToUpdate[1], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestUpdateConditions) {
    StatsdConfig config;
    // Add atom matchers. These are mostly needed for initStatsdConfig
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
    int64_t matcher4Id = matcher4.id();
    *config.add_atom_matcher() = matcher4;

    AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
    int64_t matcher5Id = matcher5.id();
    *config.add_atom_matcher() = matcher5;

    AtomMatcher matcher6 = CreateBatterySaverModeStopAtomMatcher();
    int64_t matcher6Id = matcher6.id();
    *config.add_atom_matcher() = matcher6;

    // Add the predicates.
    // Will be preserved.
    Predicate simple1 = CreateScreenIsOnPredicate();
    int64_t simple1Id = simple1.id();
    *config.add_predicate() = simple1;

    // Will be preserved.
    Predicate simple2 = CreateScheduledJobPredicate();
    int64_t simple2Id = simple2.id();
    *config.add_predicate() = simple2;

    // Will be replaced.
    Predicate simple3 = CreateBatterySaverModePredicate();
    int64_t simple3Id = simple3.id();
    *config.add_predicate() = simple3;

    // Will be preserved
    Predicate combination1;
    combination1.set_id(StringToId("COMBINATION1"));
    combination1.mutable_combination()->set_operation(LogicalOperation::AND);
    combination1.mutable_combination()->add_predicate(simple1Id);
    combination1.mutable_combination()->add_predicate(simple2Id);
    int64_t combination1Id = combination1.id();
    *config.add_predicate() = combination1;

    // Will be replaced since simple3 will be replaced.
    Predicate combination2;
    combination2.set_id(StringToId("COMBINATION2"));
    combination2.mutable_combination()->set_operation(LogicalOperation::OR);
    combination2.mutable_combination()->add_predicate(simple1Id);
    combination2.mutable_combination()->add_predicate(simple3Id);
    int64_t combination2Id = combination2.id();
    *config.add_predicate() = combination2;

    // Will be removed.
    Predicate combination3;
    combination3.set_id(StringToId("COMBINATION3"));
    combination3.mutable_combination()->set_operation(LogicalOperation::NOT);
    combination3.mutable_combination()->add_predicate(simple2Id);
    int64_t combination3Id = combination3.id();
    *config.add_predicate() = combination3;

    EXPECT_TRUE(initConfig(config));

    // Mark marcher 5 as replaced. Causes simple3, and therefore combination2 to be replaced.
    set<int64_t> replacedMatchers;
    replacedMatchers.insert(matcher6Id);

    // Change the condition of simple1 to false.
    ASSERT_EQ(oldConditionTrackers[0]->getConditionId(), simple1Id);
    LogEvent event(/*uid=*/0, /*pid=*/0);  // Empty event is fine since there are no dimensions.
    // Mark the stop matcher as matched, condition should be false.
    vector<MatchingState> eventMatcherValues(6, MatchingState::kNotMatched);
    eventMatcherValues[1] = MatchingState::kMatched;
    vector<ConditionState> tmpConditionCache(6, ConditionState::kNotEvaluated);
    vector<bool> conditionChangeCache(6, false);
    oldConditionTrackers[0]->evaluateCondition(event, eventMatcherValues, oldConditionTrackers,
                                               tmpConditionCache, conditionChangeCache);
    EXPECT_EQ(tmpConditionCache[0], ConditionState::kFalse);
    EXPECT_EQ(conditionChangeCache[0], true);

    // New combination predicate. Should have an initial condition of true since it is NOT(simple1).
    Predicate combination4;
    combination4.set_id(StringToId("COMBINATION4"));
    combination4.mutable_combination()->set_operation(LogicalOperation::NOT);
    combination4.mutable_combination()->add_predicate(simple1Id);
    int64_t combination4Id = combination4.id();
    *config.add_predicate() = combination4;

    // Map the matchers in reverse order to force the indices to change.
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    const int matcher6Index = 0;
    newAtomMatchingTrackerMap[matcher6Id] = 0;
    const int matcher5Index = 1;
    newAtomMatchingTrackerMap[matcher5Id] = 1;
    const int matcher4Index = 2;
    newAtomMatchingTrackerMap[matcher4Id] = 2;
    const int matcher3Index = 3;
    newAtomMatchingTrackerMap[matcher3Id] = 3;
    const int matcher2Index = 4;
    newAtomMatchingTrackerMap[matcher2Id] = 4;
    const int matcher1Index = 5;
    newAtomMatchingTrackerMap[matcher1Id] = 5;

    StatsdConfig newConfig;
    *newConfig.add_predicate() = simple3;
    const int simple3Index = 0;
    *newConfig.add_predicate() = combination2;
    const int combination2Index = 1;
    *newConfig.add_predicate() = combination4;
    const int combination4Index = 2;
    *newConfig.add_predicate() = simple2;
    const int simple2Index = 3;
    *newConfig.add_predicate() = combination1;
    const int combination1Index = 4;
    *newConfig.add_predicate() = simple1;
    const int simple1Index = 5;

    unordered_map<int64_t, int> newConditionTrackerMap;
    vector<sp<ConditionTracker>> newConditionTrackers;
    unordered_map<int, vector<int>> trackerToConditionMap;
    std::vector<ConditionState> conditionCache;
    std::set<int64_t> replacedConditions;
    EXPECT_TRUE(updateConditions(key, newConfig, newAtomMatchingTrackerMap, replacedMatchers,
                                 oldConditionTrackerMap, oldConditionTrackers,
                                 newConditionTrackerMap, newConditionTrackers,
                                 trackerToConditionMap, conditionCache, replacedConditions));

    unordered_map<int64_t, int> expectedConditionTrackerMap = {
            {simple1Id, simple1Index},           {simple2Id, simple2Index},
            {simple3Id, simple3Index},           {combination1Id, combination1Index},
            {combination2Id, combination2Index}, {combination4Id, combination4Index},
    };
    EXPECT_THAT(newConditionTrackerMap, ContainerEq(expectedConditionTrackerMap));

    ASSERT_EQ(newConditionTrackers.size(), 6);
    // Make sure all conditions are initialized:
    for (const sp<ConditionTracker>& tracker : newConditionTrackers) {
        EXPECT_TRUE(tracker->mInitialized);
    }

    // Make sure preserved conditions are the same.
    EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple1Id)],
              newConditionTrackers[newConditionTrackerMap.at(simple1Id)]);
    EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple2Id)],
              newConditionTrackers[newConditionTrackerMap.at(simple2Id)]);
    EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(combination1Id)],
              newConditionTrackers[newConditionTrackerMap.at(combination1Id)]);

    // Make sure replaced conditions are different and included in replacedConditions.
    EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(simple3Id)],
              newConditionTrackers[newConditionTrackerMap.at(simple3Id)]);
    EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(combination2Id)],
              newConditionTrackers[newConditionTrackerMap.at(combination2Id)]);
    EXPECT_THAT(replacedConditions, ContainerEq(set({simple3Id, combination2Id})));

    // Verify the trackerToConditionMap
    ASSERT_EQ(trackerToConditionMap.size(), 6);
    const vector<int>& matcher1Conditions = trackerToConditionMap[matcher1Index];
    EXPECT_THAT(matcher1Conditions, UnorderedElementsAre(simple1Index, combination1Index,
                                                         combination2Index, combination4Index));
    const vector<int>& matcher2Conditions = trackerToConditionMap[matcher2Index];
    EXPECT_THAT(matcher2Conditions, UnorderedElementsAre(simple1Index, combination1Index,
                                                         combination2Index, combination4Index));
    const vector<int>& matcher3Conditions = trackerToConditionMap[matcher3Index];
    EXPECT_THAT(matcher3Conditions, UnorderedElementsAre(simple2Index, combination1Index));
    const vector<int>& matcher4Conditions = trackerToConditionMap[matcher4Index];
    EXPECT_THAT(matcher4Conditions, UnorderedElementsAre(simple2Index, combination1Index));
    const vector<int>& matcher5Conditions = trackerToConditionMap[matcher5Index];
    EXPECT_THAT(matcher5Conditions, UnorderedElementsAre(simple3Index, combination2Index));
    const vector<int>& matcher6Conditions = trackerToConditionMap[matcher6Index];
    EXPECT_THAT(matcher6Conditions, UnorderedElementsAre(simple3Index, combination2Index));

    // Verify the conditionCache. Specifically, simple1 is false and combination4 is true.
    ASSERT_EQ(conditionCache.size(), 6);
    EXPECT_EQ(conditionCache[simple1Index], ConditionState::kFalse);
    EXPECT_EQ(conditionCache[simple2Index], ConditionState::kUnknown);
    EXPECT_EQ(conditionCache[simple3Index], ConditionState::kUnknown);
    EXPECT_EQ(conditionCache[combination1Index], ConditionState::kUnknown);
    EXPECT_EQ(conditionCache[combination2Index], ConditionState::kUnknown);
    EXPECT_EQ(conditionCache[combination4Index], ConditionState::kTrue);

    // Verify tracker indices/ids are correct.
    EXPECT_EQ(newConditionTrackers[simple1Index]->getConditionId(), simple1Id);
    EXPECT_EQ(newConditionTrackers[simple1Index]->mIndex, simple1Index);
    EXPECT_TRUE(newConditionTrackers[simple1Index]->IsSimpleCondition());
    EXPECT_EQ(newConditionTrackers[simple2Index]->getConditionId(), simple2Id);
    EXPECT_EQ(newConditionTrackers[simple2Index]->mIndex, simple2Index);
    EXPECT_TRUE(newConditionTrackers[simple2Index]->IsSimpleCondition());
    EXPECT_EQ(newConditionTrackers[simple3Index]->getConditionId(), simple3Id);
    EXPECT_EQ(newConditionTrackers[simple3Index]->mIndex, simple3Index);
    EXPECT_TRUE(newConditionTrackers[simple3Index]->IsSimpleCondition());
    EXPECT_EQ(newConditionTrackers[combination1Index]->getConditionId(), combination1Id);
    EXPECT_EQ(newConditionTrackers[combination1Index]->mIndex, combination1Index);
    EXPECT_FALSE(newConditionTrackers[combination1Index]->IsSimpleCondition());
    EXPECT_EQ(newConditionTrackers[combination2Index]->getConditionId(), combination2Id);
    EXPECT_EQ(newConditionTrackers[combination2Index]->mIndex, combination2Index);
    EXPECT_FALSE(newConditionTrackers[combination2Index]->IsSimpleCondition());
    EXPECT_EQ(newConditionTrackers[combination4Index]->getConditionId(), combination4Id);
    EXPECT_EQ(newConditionTrackers[combination4Index]->mIndex, combination4Index);
    EXPECT_FALSE(newConditionTrackers[combination4Index]->IsSimpleCondition());

    // Verify preserved trackers have indices updated.
    SimpleConditionTracker* simpleTracker1 =
            static_cast<SimpleConditionTracker*>(newConditionTrackers[simple1Index].get());
    EXPECT_EQ(simpleTracker1->mStartLogMatcherIndex, matcher1Index);
    EXPECT_EQ(simpleTracker1->mStopLogMatcherIndex, matcher2Index);
    EXPECT_EQ(simpleTracker1->mStopAllLogMatcherIndex, -1);

    SimpleConditionTracker* simpleTracker2 =
            static_cast<SimpleConditionTracker*>(newConditionTrackers[simple2Index].get());
    EXPECT_EQ(simpleTracker2->mStartLogMatcherIndex, matcher3Index);
    EXPECT_EQ(simpleTracker2->mStopLogMatcherIndex, matcher4Index);
    EXPECT_EQ(simpleTracker2->mStopAllLogMatcherIndex, -1);

    CombinationConditionTracker* combinationTracker1 = static_cast<CombinationConditionTracker*>(
            newConditionTrackers[combination1Index].get());
    EXPECT_THAT(combinationTracker1->mChildren, UnorderedElementsAre(simple1Index, simple2Index));
    EXPECT_THAT(combinationTracker1->mUnSlicedChildren,
                UnorderedElementsAre(simple1Index, simple2Index));
    EXPECT_THAT(combinationTracker1->mSlicedChildren, IsEmpty());
}

TEST_F(ConfigUpdateTest, TestUpdateStates) {
    StatsdConfig config;
    // Add states.
    // Will be replaced because we add a state map.
    State state1 = CreateScreenState();
    int64_t state1Id = state1.id();
    *config.add_state() = state1;

    // Will be preserved.
    State state2 = CreateUidProcessState();
    int64_t state2Id = state2.id();
    *config.add_state() = state2;

    // Will be replaced since the atom changes from overlay to screen.
    State state3 = CreateOverlayState();
    int64_t state3Id = state3.id();
    *config.add_state() = state3;

    EXPECT_TRUE(initConfig(config));

    // Change definitions of state1 and state3.
    int64_t screenOnId = 0x4321, screenOffId = 0x1234;
    *state1.mutable_map() = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
    state3.set_atom_id(util::SCREEN_STATE_CHANGED);

    StatsdConfig newConfig;
    *newConfig.add_state() = state3;
    *newConfig.add_state() = state1;
    *newConfig.add_state() = state2;

    unordered_map<int64_t, int> stateAtomIdMap;
    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
    map<int64_t, uint64_t> newStateProtoHashes;
    set<int64_t> replacedStates;
    EXPECT_TRUE(updateStates(newConfig, oldStateHashes, stateAtomIdMap, allStateGroupMaps,
                             newStateProtoHashes, replacedStates));
    EXPECT_THAT(replacedStates, ContainerEq(set({state1Id, state3Id})));

    unordered_map<int64_t, int> expectedStateAtomIdMap = {
            {state1Id, util::SCREEN_STATE_CHANGED},
            {state2Id, util::UID_PROCESS_STATE_CHANGED},
            {state3Id, util::SCREEN_STATE_CHANGED}};
    EXPECT_THAT(stateAtomIdMap, ContainerEq(expectedStateAtomIdMap));

    unordered_map<int64_t, unordered_map<int, int64_t>> expectedStateGroupMaps = {
            {state1Id,
             {{android::view::DisplayStateEnum::DISPLAY_STATE_OFF, screenOffId},
              {android::view::DisplayStateEnum::DISPLAY_STATE_ON, screenOnId}}}};
    EXPECT_THAT(allStateGroupMaps, ContainerEq(expectedStateGroupMaps));
}

TEST_F(ConfigUpdateTest, TestEventMetricPreserve) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    EventMetric* metric = config.add_event_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestEventMetricActivationAdded) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    EventMetric* metric = config.add_event_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    // Add a metric activation, which should change the proto, causing replacement.
    MetricActivation* activation = config.add_metric_activation();
    activation->set_metric_id(12345);
    EventActivation* eventActivation = activation->add_event_activation();
    eventActivation->set_atom_matcher_id(startMatcher.id());
    eventActivation->set_ttl_seconds(5);

    unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestEventMetricWhatChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    EventMetric* metric = config.add_event_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestEventMetricConditionChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    EventMetric* metric = config.add_event_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestMetricConditionLinkDepsChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    Predicate linkPredicate = CreateScreenIsOffPredicate();
    *config.add_predicate() = linkPredicate;

    EventMetric* metric = config.add_event_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());
    // Doesn't make sense as a real metric definition, but suffices as a separate predicate
    // From the one in the condition.
    MetricConditionLink* link = metric->add_links();
    link->set_condition(linkPredicate.id());

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{linkPredicate.id()},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestEventMetricActivationDepsChange) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    EventMetric* metric = config.add_event_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());

    MetricActivation* activation = config.add_metric_activation();
    activation->set_metric_id(12345);
    EventActivation* eventActivation = activation->add_event_activation();
    eventActivation->set_atom_matcher_id(startMatcher.id());
    eventActivation->set_ttl_seconds(5);

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {startMatcher.id()}, /*replacedConditions=*/{},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestCountMetricPreserve) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;
    State sliceState = CreateScreenState();
    *config.add_state() = sliceState;

    CountMetric* metric = config.add_count_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());
    metric->add_slice_by_state(sliceState.id());
    metric->set_bucket(ONE_HOUR);

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestCountMetricDefinitionChange) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    CountMetric* metric = config.add_count_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());
    metric->set_bucket(ONE_HOUR);

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    // Change bucket size, which should change the proto, causing replacement.
    metric->set_bucket(TEN_MINUTES);

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestCountMetricWhatChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    CountMetric* metric = config.add_count_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());
    metric->set_bucket(ONE_HOUR);

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestCountMetricConditionChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    CountMetric* metric = config.add_count_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->set_condition(predicate.id());
    metric->set_bucket(ONE_HOUR);

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestCountMetricStateChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    State sliceState = CreateScreenState();
    *config.add_state() = sliceState;

    CountMetric* metric = config.add_count_metric();
    metric->set_id(12345);
    metric->set_what(whatMatcher.id());
    metric->add_slice_by_state(sliceState.id());
    metric->set_bucket(ONE_HOUR);

    // Create an initial config.
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{},
            /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestGaugeMetricPreserve) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    *config.add_gauge_metric() = createGaugeMetric(
            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);

    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestGaugeMetricDefinitionChange) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    *config.add_gauge_metric() = createGaugeMetric(
            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);

    EXPECT_TRUE(initConfig(config));

    // Change split bucket on app upgrade, which should change the proto, causing replacement.
    config.mutable_gauge_metric(0)->set_split_bucket_for_app_upgrade(false);

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestGaugeMetricWhatChanged) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    *config.add_gauge_metric() = createGaugeMetric(
            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);

    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestGaugeMetricConditionChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    *config.add_gauge_metric() = createGaugeMetric(
            "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);

    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestGaugeMetricTriggerEventChanged) {
    StatsdConfig config;
    AtomMatcher triggerEvent = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = triggerEvent;
    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    *config.add_gauge_metric() = createGaugeMetric(
            "GAUGE1", whatMatcher.id(), GaugeMetric::FIRST_N_SAMPLES, nullopt, triggerEvent.id());

    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {triggerEvent.id()}, /*replacedConditions=*/{},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestDurationMetricPreserve) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate what = CreateScreenIsOnPredicate();
    *config.add_predicate() = what;
    Predicate condition = CreateScreenIsOffPredicate();
    *config.add_predicate() = condition;

    State sliceState = CreateScreenState();
    *config.add_state() = sliceState;

    *config.add_duration_metric() =
            createDurationMetric("DURATION1", what.id(), condition.id(), {sliceState.id()});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestDurationMetricDefinitionChange) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate what = CreateScreenIsOnPredicate();
    *config.add_predicate() = what;

    *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
    EXPECT_TRUE(initConfig(config));

    config.mutable_duration_metric(0)->set_aggregation_type(DurationMetric::MAX_SPARSE);

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap, /*replacedMatchers*/ {},
                                                 /*replacedConditions=*/{}, /*replacedStates=*/{},
                                                 metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestDurationMetricWhatChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate what = CreateScreenIsOnPredicate();
    *config.add_predicate() = what;

    *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{what.id()},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestDurationMetricConditionChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate what = CreateScreenIsOnPredicate();
    *config.add_predicate() = what;
    Predicate condition = CreateScreenIsOffPredicate();
    *config.add_predicate() = condition;

    *config.add_duration_metric() = createDurationMetric("DURATION", what.id(), condition.id(), {});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{condition.id()},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestDurationMetricStateChange) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;

    Predicate what = CreateScreenIsOnPredicate();
    *config.add_predicate() = what;

    State sliceState = CreateScreenState();
    *config.add_state() = sliceState;

    *config.add_duration_metric() =
            createDurationMetric("DURATION1", what.id(), nullopt, {sliceState.id()});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{},
            /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestValueMetricPreserve) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;
    State sliceState = CreateScreenState();
    *config.add_state() = sliceState;

    *config.add_value_metric() =
            createValueMetric("VALUE1", whatMatcher, predicate.id(), {sliceState.id()});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestValueMetricDefinitionChange) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, nullopt, {});
    EXPECT_TRUE(initConfig(config));

    // Change skip zero diff output, which should change the proto, causing replacement.
    config.mutable_value_metric(0)->set_skip_zero_diff_output(true);

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
                                                 metricToActivationMap,
                                                 /*replacedMatchers*/ {}, /*replacedConditions=*/{},
                                                 /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestValueMetricWhatChanged) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, nullopt, {});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestValueMetricConditionChanged) {
    StatsdConfig config;
    AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = startMatcher;
    AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
    *config.add_atom_matcher() = stopMatcher;
    AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    Predicate predicate = CreateScreenIsOnPredicate();
    *config.add_predicate() = predicate;

    *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, predicate.id(), {});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
            /*replacedStates=*/{}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestValueMetricStateChanged) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    State sliceState = CreateScreenState();
    *config.add_state() = sliceState;

    *config.add_value_metric() =
            createValueMetric("VALUE1", whatMatcher, nullopt, {sliceState.id()});
    EXPECT_TRUE(initConfig(config));

    unordered_map<int64_t, int> metricToActivationMap;
    vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
    EXPECT_TRUE(determineAllMetricUpdateStatuses(
            config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
            /*replacedMatchers*/ {}, /*replacedConditions=*/{},
            /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
    EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) {
    StatsdConfig config;

    // Add atom matchers/predicates. These are mostly needed for initStatsdConfig
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
    int64_t matcher4Id = matcher4.id();
    *config.add_atom_matcher() = matcher4;

    AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
    int64_t matcher5Id = matcher5.id();
    *config.add_atom_matcher() = matcher5;

    Predicate predicate1 = CreateScreenIsOnPredicate();
    int64_t predicate1Id = predicate1.id();
    *config.add_predicate() = predicate1;

    Predicate predicate2 = CreateScheduledJobPredicate();
    int64_t predicate2Id = predicate2.id();
    *config.add_predicate() = predicate2;

    // Add a few event metrics.
    // Will be preserved.
    EventMetric event1 = createEventMetric("EVENT1", matcher1Id, predicate2Id);
    int64_t event1Id = event1.id();
    *config.add_event_metric() = event1;

    // Will be replaced.
    EventMetric event2 = createEventMetric("EVENT2", matcher2Id, nullopt);
    int64_t event2Id = event2.id();
    *config.add_event_metric() = event2;

    // Will be replaced.
    EventMetric event3 = createEventMetric("EVENT3", matcher3Id, nullopt);
    int64_t event3Id = event3.id();
    *config.add_event_metric() = event3;

    MetricActivation event3Activation;
    event3Activation.set_metric_id(event3Id);
    EventActivation* eventActivation = event3Activation.add_event_activation();
    eventActivation->set_atom_matcher_id(matcher5Id);
    eventActivation->set_ttl_seconds(5);
    *config.add_metric_activation() = event3Activation;

    // Will be replaced.
    EventMetric event4 = createEventMetric("EVENT4", matcher4Id, predicate1Id);
    int64_t event4Id = event4.id();
    *config.add_event_metric() = event4;

    // Will be deleted.
    EventMetric event5 = createEventMetric("EVENT5", matcher5Id, nullopt);
    int64_t event5Id = event5.id();
    *config.add_event_metric() = event5;

    EXPECT_TRUE(initConfig(config));

    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
    sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
    EXPECT_EQ(oldConditionWizard->getStrongCount(), oldMetricProducers.size() + 1);

    // Add a condition to event2, causing it to be replaced.
    event2.set_condition(predicate1Id);

    // Mark matcher 5 as replaced. Causes event3 to be replaced.
    set<int64_t> replacedMatchers;
    replacedMatchers.insert(matcher5Id);

    // Mark predicate 1 as replaced. Causes event4 to be replaced.
    set<int64_t> replacedConditions;
    replacedConditions.insert(predicate1Id);

    // Fake that predicate 2 is true.
    ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
    oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
    EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);

    // New event metric. Should have an initial condition of true since it depends on predicate2.
    EventMetric event6 = createEventMetric("EVENT6", matcher3Id, predicate2Id);
    int64_t event6Id = event6.id();
    MetricActivation event6Activation;
    event6Activation.set_metric_id(event6Id);
    eventActivation = event6Activation.add_event_activation();
    eventActivation->set_atom_matcher_id(matcher5Id);
    eventActivation->set_ttl_seconds(20);

    // Map the matchers and predicates in reverse order to force the indices to change.
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    const int matcher5Index = 0;
    newAtomMatchingTrackerMap[matcher5Id] = 0;
    const int matcher4Index = 1;
    newAtomMatchingTrackerMap[matcher4Id] = 1;
    const int matcher3Index = 2;
    newAtomMatchingTrackerMap[matcher3Id] = 2;
    const int matcher2Index = 3;
    newAtomMatchingTrackerMap[matcher2Id] = 3;
    const int matcher1Index = 4;
    newAtomMatchingTrackerMap[matcher1Id] = 4;
    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
                      newAtomMatchingTrackers.begin());

    std::unordered_map<int64_t, int> newConditionTrackerMap;
    const int predicate2Index = 0;
    newConditionTrackerMap[predicate2Id] = 0;
    const int predicate1Index = 1;
    newConditionTrackerMap[predicate1Id] = 1;
    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<ConditionTracker>> newConditionTrackers(2);
    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
                      newConditionTrackers.begin());
    // Fake that predicate2 is true.
    vector<ConditionState> conditionCache = {ConditionState::kTrue, ConditionState::kUnknown};

    StatsdConfig newConfig;
    *newConfig.add_event_metric() = event6;
    const int event6Index = 0;
    *newConfig.add_event_metric() = event3;
    const int event3Index = 1;
    *newConfig.add_event_metric() = event1;
    const int event1Index = 2;
    *newConfig.add_event_metric() = event4;
    const int event4Index = 3;
    *newConfig.add_event_metric() = event2;
    const int event2Index = 4;
    *newConfig.add_metric_activation() = event3Activation;
    *newConfig.add_metric_activation() = event6Activation;

    // Output data structures to validate.
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
            newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    unordered_map<int64_t, int> expectedMetricProducerMap = {
            {event1Id, event1Index}, {event2Id, event2Index}, {event3Id, event3Index},
            {event4Id, event4Index}, {event6Id, event6Index},
    };
    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
    EXPECT_EQ(replacedMetrics, set<int64_t>({event2Id, event3Id, event4Id}));

    // Make sure preserved metrics are the same.
    ASSERT_EQ(newMetricProducers.size(), 5);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(event1Id)],
              newMetricProducers[newMetricProducerMap.at(event1Id)]);

    // Make sure replaced metrics are different.
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event2Id)],
              newMetricProducers[newMetricProducerMap.at(event2Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event3Id)],
              newMetricProducers[newMetricProducerMap.at(event3Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event4Id)],
              newMetricProducers[newMetricProducerMap.at(event4Id)]);

    // Verify the conditionToMetricMap.
    ASSERT_EQ(conditionToMetricMap.size(), 2);
    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(event2Index, event4Index));
    const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
    EXPECT_THAT(condition2Metrics, UnorderedElementsAre(event1Index, event6Index));

    // Verify the trackerToMetricMap.
    ASSERT_EQ(trackerToMetricMap.size(), 4);
    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(event1Index));
    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(event2Index));
    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(event3Index, event6Index));
    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(event4Index));

    // Verify event activation/deactivation maps.
    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 1);
    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher5Index],
                UnorderedElementsAre(event3Index, event6Index));
    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(metricsWithActivation.size(), 2);
    EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(event3Index, event6Index));

    // Verify tracker indices/ids/conditions are correct.
    EXPECT_EQ(newMetricProducers[event1Index]->getMetricId(), event1Id);
    EXPECT_EQ(newMetricProducers[event1Index]->mConditionTrackerIndex, predicate2Index);
    EXPECT_EQ(newMetricProducers[event1Index]->mCondition, ConditionState::kTrue);
    EXPECT_EQ(newMetricProducers[event2Index]->getMetricId(), event2Id);
    EXPECT_EQ(newMetricProducers[event2Index]->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(newMetricProducers[event2Index]->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(newMetricProducers[event3Index]->getMetricId(), event3Id);
    EXPECT_EQ(newMetricProducers[event3Index]->mConditionTrackerIndex, -1);
    EXPECT_EQ(newMetricProducers[event3Index]->mCondition, ConditionState::kTrue);
    EXPECT_EQ(newMetricProducers[event4Index]->getMetricId(), event4Id);
    EXPECT_EQ(newMetricProducers[event4Index]->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(newMetricProducers[event4Index]->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(newMetricProducers[event6Index]->getMetricId(), event6Id);
    EXPECT_EQ(newMetricProducers[event6Index]->mConditionTrackerIndex, predicate2Index);
    EXPECT_EQ(newMetricProducers[event6Index]->mCondition, ConditionState::kTrue);

    sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
    EXPECT_NE(newConditionWizard, oldConditionWizard);
    EXPECT_EQ(newConditionWizard->getStrongCount(), newMetricProducers.size() + 1);
    oldMetricProducers.clear();
    // Only reference to the old wizard should be the one in the test.
    EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
}

TEST_F(ConfigUpdateTest, TestUpdateCountMetrics) {
    StatsdConfig config;

    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
    int64_t matcher4Id = matcher4.id();
    *config.add_atom_matcher() = matcher4;

    AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
    int64_t matcher5Id = matcher5.id();
    *config.add_atom_matcher() = matcher5;

    Predicate predicate1 = CreateScreenIsOnPredicate();
    int64_t predicate1Id = predicate1.id();
    *config.add_predicate() = predicate1;

    State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
    int64_t state1Id = state1.id();
    *config.add_state() = state1;

    State state2 = CreateScreenState();
    int64_t state2Id = state2.id();
    *config.add_state() = state2;

    // Add a few count metrics.
    // Will be preserved.
    CountMetric count1 = createCountMetric("COUNT1", matcher1Id, predicate1Id, {state1Id});
    int64_t count1Id = count1.id();
    *config.add_count_metric() = count1;

    // Will be replaced.
    CountMetric count2 = createCountMetric("COUNT2", matcher2Id, nullopt, {});
    int64_t count2Id = count2.id();
    *config.add_count_metric() = count2;

    // Will be replaced.
    CountMetric count3 = createCountMetric("COUNT3", matcher3Id, nullopt, {});
    int64_t count3Id = count3.id();
    *config.add_count_metric() = count3;

    // Will be replaced.
    CountMetric count4 = createCountMetric("COUNT4", matcher4Id, nullopt, {state2Id});
    int64_t count4Id = count4.id();
    *config.add_count_metric() = count4;

    // Will be deleted.
    CountMetric count5 = createCountMetric("COUNT5", matcher5Id, nullopt, {});
    int64_t count5Id = count5.id();
    *config.add_count_metric() = count5;

    EXPECT_TRUE(initConfig(config));

    // Change bucket size of count2, causing it to be replaced.
    count2.set_bucket(ONE_HOUR);

    // Mark matcher 3 as replaced. Causes count3 to be replaced.
    set<int64_t> replacedMatchers;
    replacedMatchers.insert(matcher3Id);

    // Mark state 2 as replaced and change the state to be about a different atom.
    // Causes count4 to be replaced.
    set<int64_t> replacedStates;
    replacedStates.insert(state2Id);
    state2.set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);

    // Fake that predicate 1 is true for count metric 1.
    ASSERT_EQ(oldMetricProducers[0]->getMetricId(), count1Id);
    oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
    EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);

    EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 1);
    // Tell the StateManager that the screen is on.
    unique_ptr<LogEvent> event =
            CreateScreenStateChangedEvent(0, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
    StateManager::getInstance().onLogEvent(*event);

    // New count metric. Should have an initial condition of true since it depends on predicate1.
    CountMetric count6 = createCountMetric("EVENT6", matcher2Id, predicate1Id, {state1Id});
    int64_t count6Id = count6.id();

    // Map the matchers and predicates in reverse order to force the indices to change.
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    const int matcher5Index = 0;
    newAtomMatchingTrackerMap[matcher5Id] = 0;
    const int matcher4Index = 1;
    newAtomMatchingTrackerMap[matcher4Id] = 1;
    const int matcher3Index = 2;
    newAtomMatchingTrackerMap[matcher3Id] = 2;
    const int matcher2Index = 3;
    newAtomMatchingTrackerMap[matcher2Id] = 3;
    const int matcher1Index = 4;
    newAtomMatchingTrackerMap[matcher1Id] = 4;
    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
                      newAtomMatchingTrackers.begin());

    std::unordered_map<int64_t, int> newConditionTrackerMap;
    const int predicate1Index = 0;
    newConditionTrackerMap[predicate1Id] = 0;
    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<ConditionTracker>> newConditionTrackers(1);
    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
                      newConditionTrackers.begin());
    // Fake that predicate1 is true for all new metrics.
    vector<ConditionState> conditionCache = {ConditionState::kTrue};

    StatsdConfig newConfig;
    *newConfig.add_count_metric() = count6;
    const int count6Index = 0;
    *newConfig.add_count_metric() = count3;
    const int count3Index = 1;
    *newConfig.add_count_metric() = count1;
    const int count1Index = 2;
    *newConfig.add_count_metric() = count4;
    const int count4Index = 3;
    *newConfig.add_count_metric() = count2;
    const int count2Index = 4;

    *newConfig.add_state() = state1;
    *newConfig.add_state() = state2;

    unordered_map<int64_t, int> stateAtomIdMap;
    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
    map<int64_t, uint64_t> stateProtoHashes;
    EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));
    EXPECT_EQ(stateAtomIdMap[state2Id], util::BATTERY_SAVER_MODE_STATE_CHANGED);

    // Output data structures to validate.
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
            newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
            newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    unordered_map<int64_t, int> expectedMetricProducerMap = {
            {count1Id, count1Index}, {count2Id, count2Index}, {count3Id, count3Index},
            {count4Id, count4Index}, {count6Id, count6Index},
    };
    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
    EXPECT_EQ(replacedMetrics, set<int64_t>({count2Id, count3Id, count4Id}));

    // Make sure preserved metrics are the same.
    ASSERT_EQ(newMetricProducers.size(), 5);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(count1Id)],
              newMetricProducers[newMetricProducerMap.at(count1Id)]);

    // Make sure replaced metrics are different.
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count2Id)],
              newMetricProducers[newMetricProducerMap.at(count2Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count3Id)],
              newMetricProducers[newMetricProducerMap.at(count3Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count4Id)],
              newMetricProducers[newMetricProducerMap.at(count4Id)]);

    // Verify the conditionToMetricMap.
    ASSERT_EQ(conditionToMetricMap.size(), 1);
    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(count1Index, count6Index));

    // Verify the trackerToMetricMap.
    ASSERT_EQ(trackerToMetricMap.size(), 4);
    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(count1Index));
    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(count2Index, count6Index));
    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(count3Index));
    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(count4Index));

    // Verify event activation/deactivation maps.
    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(metricsWithActivation.size(), 0);

    // Verify tracker indices/ids/conditions/states are correct.
    EXPECT_EQ(newMetricProducers[count1Index]->getMetricId(), count1Id);
    EXPECT_EQ(newMetricProducers[count1Index]->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(newMetricProducers[count1Index]->mCondition, ConditionState::kTrue);
    EXPECT_THAT(newMetricProducers[count1Index]->getSlicedStateAtoms(),
                UnorderedElementsAre(util::SCREEN_STATE_CHANGED));
    EXPECT_EQ(newMetricProducers[count2Index]->getMetricId(), count2Id);
    EXPECT_EQ(newMetricProducers[count2Index]->mConditionTrackerIndex, -1);
    EXPECT_EQ(newMetricProducers[count2Index]->mCondition, ConditionState::kTrue);
    EXPECT_TRUE(newMetricProducers[count2Index]->getSlicedStateAtoms().empty());
    EXPECT_EQ(newMetricProducers[count3Index]->getMetricId(), count3Id);
    EXPECT_EQ(newMetricProducers[count3Index]->mConditionTrackerIndex, -1);
    EXPECT_EQ(newMetricProducers[count3Index]->mCondition, ConditionState::kTrue);
    EXPECT_TRUE(newMetricProducers[count3Index]->getSlicedStateAtoms().empty());
    EXPECT_EQ(newMetricProducers[count4Index]->getMetricId(), count4Id);
    EXPECT_EQ(newMetricProducers[count4Index]->mConditionTrackerIndex, -1);
    EXPECT_EQ(newMetricProducers[count4Index]->mCondition, ConditionState::kTrue);
    EXPECT_THAT(newMetricProducers[count4Index]->getSlicedStateAtoms(),
                UnorderedElementsAre(util::BATTERY_SAVER_MODE_STATE_CHANGED));
    EXPECT_EQ(newMetricProducers[count6Index]->getMetricId(), count6Id);
    EXPECT_EQ(newMetricProducers[count6Index]->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(newMetricProducers[count6Index]->mCondition, ConditionState::kTrue);
    EXPECT_THAT(newMetricProducers[count6Index]->getSlicedStateAtoms(),
                UnorderedElementsAre(util::SCREEN_STATE_CHANGED));

    oldMetricProducers.clear();
    // Ensure that the screen state StateTracker did not get deleted and replaced.
    EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 2);
    FieldValue screenState;
    StateManager::getInstance().getStateValue(util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY,
                                              &screenState);
    EXPECT_EQ(screenState.mValue.int_value, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
}

TEST_F(ConfigUpdateTest, TestUpdateGaugeMetrics) {
    StatsdConfig config;

    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
    int64_t matcher4Id = matcher4.id();
    *config.add_atom_matcher() = matcher4;

    AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
    int64_t matcher5Id = matcher5.id();
    *config.add_atom_matcher() = matcher5;

    Predicate predicate1 = CreateScreenIsOnPredicate();
    int64_t predicate1Id = predicate1.id();
    *config.add_predicate() = predicate1;

    // Add a few gauge metrics.
    // Will be preserved.
    GaugeMetric gauge1 = createGaugeMetric("GAUGE1", matcher4Id, GaugeMetric::FIRST_N_SAMPLES,
                                           predicate1Id, matcher1Id);
    int64_t gauge1Id = gauge1.id();
    *config.add_gauge_metric() = gauge1;

    // Will be replaced.
    GaugeMetric gauge2 =
            createGaugeMetric("GAUGE2", matcher1Id, GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
    int64_t gauge2Id = gauge2.id();
    *config.add_gauge_metric() = gauge2;

    // Will be replaced.
    GaugeMetric gauge3 = createGaugeMetric("GAUGE3", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
                                           nullopt, matcher3Id);
    int64_t gauge3Id = gauge3.id();
    *config.add_gauge_metric() = gauge3;

    // Will be replaced.
    GaugeMetric gauge4 = createGaugeMetric("GAUGE4", matcher3Id, GaugeMetric::RANDOM_ONE_SAMPLE,
                                           predicate1Id, nullopt);
    int64_t gauge4Id = gauge4.id();
    *config.add_gauge_metric() = gauge4;

    // Will be deleted.
    GaugeMetric gauge5 =
            createGaugeMetric("GAUGE5", matcher2Id, GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, {});
    int64_t gauge5Id = gauge5.id();
    *config.add_gauge_metric() = gauge5;

    EXPECT_TRUE(initConfig(config));

    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
    sp<EventMatcherWizard> oldMatcherWizard =
            static_cast<GaugeMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard;
    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);

    // Change gauge2, causing it to be replaced.
    gauge2.set_max_num_gauge_atoms_per_bucket(50);

    // Mark matcher 3 as replaced. Causes gauge3 and gauge4 to be replaced.
    set<int64_t> replacedMatchers = {matcher3Id};

    // New gauge metric.
    GaugeMetric gauge6 = createGaugeMetric("GAUGE6", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
                                           predicate1Id, matcher3Id);
    int64_t gauge6Id = gauge6.id();

    // Map the matchers and predicates in reverse order to force the indices to change.
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    const int matcher5Index = 0;
    newAtomMatchingTrackerMap[matcher5Id] = 0;
    const int matcher4Index = 1;
    newAtomMatchingTrackerMap[matcher4Id] = 1;
    const int matcher3Index = 2;
    newAtomMatchingTrackerMap[matcher3Id] = 2;
    const int matcher2Index = 3;
    newAtomMatchingTrackerMap[matcher2Id] = 3;
    const int matcher1Index = 4;
    newAtomMatchingTrackerMap[matcher1Id] = 4;
    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
                      newAtomMatchingTrackers.begin());

    std::unordered_map<int64_t, int> newConditionTrackerMap;
    const int predicate1Index = 0;
    newConditionTrackerMap[predicate1Id] = 0;
    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<ConditionTracker>> newConditionTrackers(1);
    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
                      newConditionTrackers.begin());
    // Say that predicate1 is unknown since the initial condition never changed.
    vector<ConditionState> conditionCache = {ConditionState::kUnknown};

    StatsdConfig newConfig;
    *newConfig.add_gauge_metric() = gauge6;
    const int gauge6Index = 0;
    *newConfig.add_gauge_metric() = gauge3;
    const int gauge3Index = 1;
    *newConfig.add_gauge_metric() = gauge1;
    const int gauge1Index = 2;
    *newConfig.add_gauge_metric() = gauge4;
    const int gauge4Index = 3;
    *newConfig.add_gauge_metric() = gauge2;
    const int gauge2Index = 4;

    // Output data structures to validate.
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
            newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
            newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    unordered_map<int64_t, int> expectedMetricProducerMap = {
            {gauge1Id, gauge1Index}, {gauge2Id, gauge2Index}, {gauge3Id, gauge3Index},
            {gauge4Id, gauge4Index}, {gauge6Id, gauge6Index},
    };
    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
    EXPECT_EQ(replacedMetrics, set<int64_t>({gauge2Id, gauge3Id, gauge4Id}));

    // Make sure preserved metrics are the same.
    ASSERT_EQ(newMetricProducers.size(), 5);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(gauge1Id)],
              newMetricProducers[newMetricProducerMap.at(gauge1Id)]);

    // Make sure replaced metrics are different.
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge2Id)],
              newMetricProducers[newMetricProducerMap.at(gauge2Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge3Id)],
              newMetricProducers[newMetricProducerMap.at(gauge3Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge4Id)],
              newMetricProducers[newMetricProducerMap.at(gauge4Id)]);

    // Verify the conditionToMetricMap.
    ASSERT_EQ(conditionToMetricMap.size(), 1);
    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(gauge1Index, gauge4Index, gauge6Index));

    // Verify the trackerToMetricMap.
    ASSERT_EQ(trackerToMetricMap.size(), 4);
    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(gauge1Index, gauge2Index));
    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gauge3Index, gauge4Index, gauge6Index));
    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(gauge1Index));
    const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
    EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(gauge3Index, gauge6Index));

    // Verify event activation/deactivation maps.
    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(metricsWithActivation.size(), 0);

    // Verify tracker indices/ids/conditions/states are correct.
    GaugeMetricProducer* gaugeProducer1 =
            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge1Index].get());
    EXPECT_EQ(gaugeProducer1->getMetricId(), gauge1Id);
    EXPECT_EQ(gaugeProducer1->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(gaugeProducer1->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(gaugeProducer1->mWhatMatcherIndex, matcher4Index);
    GaugeMetricProducer* gaugeProducer2 =
            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge2Index].get());
    EXPECT_EQ(gaugeProducer2->getMetricId(), gauge2Id);
    EXPECT_EQ(gaugeProducer2->mConditionTrackerIndex, -1);
    EXPECT_EQ(gaugeProducer2->mCondition, ConditionState::kTrue);
    EXPECT_EQ(gaugeProducer2->mWhatMatcherIndex, matcher1Index);
    GaugeMetricProducer* gaugeProducer3 =
            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge3Index].get());
    EXPECT_EQ(gaugeProducer3->getMetricId(), gauge3Id);
    EXPECT_EQ(gaugeProducer3->mConditionTrackerIndex, -1);
    EXPECT_EQ(gaugeProducer3->mCondition, ConditionState::kTrue);
    EXPECT_EQ(gaugeProducer3->mWhatMatcherIndex, matcher5Index);
    GaugeMetricProducer* gaugeProducer4 =
            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge4Index].get());
    EXPECT_EQ(gaugeProducer4->getMetricId(), gauge4Id);
    EXPECT_EQ(gaugeProducer4->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(gaugeProducer4->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(gaugeProducer4->mWhatMatcherIndex, matcher3Index);
    GaugeMetricProducer* gaugeProducer6 =
            static_cast<GaugeMetricProducer*>(newMetricProducers[gauge6Index].get());
    EXPECT_EQ(gaugeProducer6->getMetricId(), gauge6Id);
    EXPECT_EQ(gaugeProducer6->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(gaugeProducer6->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(gaugeProducer6->mWhatMatcherIndex, matcher5Index);

    sp<EventMatcherWizard> newMatcherWizard = gaugeProducer1->mEventMatcherWizard;
    EXPECT_NE(newMatcherWizard, oldMatcherWizard);
    EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
    oldMetricProducers.clear();
    // Only reference to the old wizard should be the one in the test.
    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
}

TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) {
    StatsdConfig config;
    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateAcquireWakelockAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    AtomMatcher matcher4 = CreateReleaseWakelockAtomMatcher();
    int64_t matcher4Id = matcher4.id();
    *config.add_atom_matcher() = matcher4;

    AtomMatcher matcher5 = CreateMoveToForegroundAtomMatcher();
    int64_t matcher5Id = matcher5.id();
    *config.add_atom_matcher() = matcher5;

    AtomMatcher matcher6 = CreateMoveToBackgroundAtomMatcher();
    int64_t matcher6Id = matcher6.id();
    *config.add_atom_matcher() = matcher6;

    AtomMatcher matcher7 = CreateBatteryStateNoneMatcher();
    int64_t matcher7Id = matcher7.id();
    *config.add_atom_matcher() = matcher7;

    AtomMatcher matcher8 = CreateBatteryStateUsbMatcher();
    int64_t matcher8Id = matcher8.id();
    *config.add_atom_matcher() = matcher8;

    Predicate predicate1 = CreateScreenIsOnPredicate();
    int64_t predicate1Id = predicate1.id();
    *config.add_predicate() = predicate1;

    Predicate predicate2 = CreateScreenIsOffPredicate();
    int64_t predicate2Id = predicate2.id();
    *config.add_predicate() = predicate2;

    Predicate predicate3 = CreateDeviceUnpluggedPredicate();
    int64_t predicate3Id = predicate3.id();
    *config.add_predicate() = predicate3;

    Predicate predicate4 = CreateIsInBackgroundPredicate();
    *predicate4.mutable_simple_predicate()->mutable_dimensions() =
            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1});
    int64_t predicate4Id = predicate4.id();
    *config.add_predicate() = predicate4;

    Predicate predicate5 = CreateHoldingWakelockPredicate();
    *predicate5.mutable_simple_predicate()->mutable_dimensions() =
            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    predicate5.mutable_simple_predicate()->set_stop_all(matcher7Id);
    int64_t predicate5Id = predicate5.id();
    *config.add_predicate() = predicate5;

    State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
    int64_t state1Id = state1.id();
    *config.add_state() = state1;

    State state2 = CreateScreenState();
    int64_t state2Id = state2.id();
    *config.add_state() = state2;

    // Add a few duration metrics.
    // Will be preserved.
    DurationMetric duration1 =
            createDurationMetric("DURATION1", predicate5Id, predicate4Id, {state2Id});
    *duration1.mutable_dimensions_in_what() =
            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    MetricConditionLink* link = duration1.add_links();
    link->set_condition(predicate4Id);
    *link->mutable_fields_in_what() =
            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    *link->mutable_fields_in_condition() =
            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
    int64_t duration1Id = duration1.id();
    *config.add_duration_metric() = duration1;

    // Will be replaced.
    DurationMetric duration2 = createDurationMetric("DURATION2", predicate1Id, nullopt, {});
    int64_t duration2Id = duration2.id();
    *config.add_duration_metric() = duration2;

    // Will be replaced.
    DurationMetric duration3 = createDurationMetric("DURATION3", predicate3Id, nullopt, {state1Id});
    int64_t duration3Id = duration3.id();
    *config.add_duration_metric() = duration3;

    // Will be replaced.
    DurationMetric duration4 = createDurationMetric("DURATION4", predicate3Id, predicate2Id, {});
    int64_t duration4Id = duration4.id();
    *config.add_duration_metric() = duration4;

    // Will be deleted.
    DurationMetric duration5 = createDurationMetric("DURATION5", predicate2Id, nullopt, {});
    int64_t duration5Id = duration5.id();
    *config.add_duration_metric() = duration5;

    EXPECT_TRUE(initConfig(config));

    // Make some sliced conditions true.
    int uid1 = 10;
    int uid2 = 11;
    vector<MatchingState> matchingStates(8, MatchingState::kNotMatched);
    matchingStates[2] = kMatched;
    vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
    vector<bool> changedCache(5, false);
    unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid1}, {"tag"}, "wl1");
    oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
                                               conditionCache, changedCache);
    EXPECT_TRUE(oldConditionTrackers[4]->isSliced());
    EXPECT_TRUE(changedCache[4]);
    EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
    oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());

    fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
    fill(changedCache.begin(), changedCache.end(), false);
    event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid2}, {"tag"}, "wl2");
    oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
                                               conditionCache, changedCache);
    EXPECT_TRUE(changedCache[4]);
    EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
    oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());

    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
    // The duration trackers have a pointer to the wizard, and 2 trackers were created above.
    sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
    EXPECT_EQ(oldConditionWizard->getStrongCount(), 8);

    // Replace predicate1, predicate3, and state1. Causes duration2/3/4 to be replaced.
    set<int64_t> replacedConditions({predicate1Id, predicate2Id});
    set<int64_t> replacedStates({state1Id});

    // New duration metric.
    DurationMetric duration6 = createDurationMetric("DURATION6", predicate4Id, predicate5Id, {});
    *duration6.mutable_dimensions_in_what() =
            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
    link = duration6.add_links();
    link->set_condition(predicate5Id);
    *link->mutable_fields_in_what() =
            CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
    *link->mutable_fields_in_condition() =
            CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
    int64_t duration6Id = duration6.id();

    // Map the matchers and predicates in reverse order to force the indices to change.
    const int matcher8Index = 0, matcher7Index = 1, matcher6Index = 2, matcher5Index = 3,
              matcher4Index = 4, matcher3Index = 5, matcher2Index = 6, matcher1Index = 7;
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap({{matcher8Id, matcher8Index},
                                                                {matcher7Id, matcher7Index},
                                                                {matcher6Id, matcher6Index},
                                                                {matcher5Id, matcher5Index},
                                                                {matcher4Id, matcher4Index},
                                                                {matcher3Id, matcher3Index},
                                                                {matcher2Id, matcher2Index},
                                                                {matcher1Id, matcher1Index}});
    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(8);
    reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
                 newAtomMatchingTrackers.begin());

    const int predicate5Index = 0, predicate4Index = 1, predicate3Index = 2, predicate2Index = 3,
              predicate1Index = 4;
    std::unordered_map<int64_t, int> newConditionTrackerMap({
            {predicate5Id, predicate5Index},
            {predicate4Id, predicate4Index},
            {predicate3Id, predicate3Index},
            {predicate2Id, predicate2Index},
            {predicate1Id, predicate1Index},
    });
    // Use the existing conditionTrackers and reinitialize them to get the initial condition cache.
    vector<sp<ConditionTracker>> newConditionTrackers(5);
    reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
                 newConditionTrackers.begin());
    vector<Predicate> conditionProtos(5);
    reverse_copy(config.predicate().begin(), config.predicate().end(), conditionProtos.begin());
    for (int i = 0; i < newConditionTrackers.size(); i++) {
        EXPECT_TRUE(newConditionTrackers[i]->onConfigUpdated(
                conditionProtos, i, newConditionTrackers, newAtomMatchingTrackerMap,
                newConditionTrackerMap));
    }
    vector<bool> cycleTracker(5, false);
    fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
    for (int i = 0; i < newConditionTrackers.size(); i++) {
        EXPECT_TRUE(newConditionTrackers[i]->init(conditionProtos, newConditionTrackers,
                                                  newConditionTrackerMap, cycleTracker,
                                                  conditionCache));
    }
    // Predicate5 should be true since 2 uids have wakelocks
    EXPECT_EQ(conditionCache, vector({kTrue, kUnknown, kUnknown, kUnknown, kUnknown}));

    StatsdConfig newConfig;
    *newConfig.add_duration_metric() = duration6;
    const int duration6Index = 0;
    *newConfig.add_duration_metric() = duration3;
    const int duration3Index = 1;
    *newConfig.add_duration_metric() = duration1;
    const int duration1Index = 2;
    *newConfig.add_duration_metric() = duration4;
    const int duration4Index = 3;
    *newConfig.add_duration_metric() = duration2;
    const int duration2Index = 4;

    for (const Predicate& predicate : conditionProtos) {
        *newConfig.add_predicate() = predicate;
    }
    *newConfig.add_state() = state1;
    *newConfig.add_state() = state2;
    unordered_map<int64_t, int> stateAtomIdMap;
    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
    map<int64_t, uint64_t> stateProtoHashes;
    EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));

    // Output data structures to validate.
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
            newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    unordered_map<int64_t, int> expectedMetricProducerMap = {
            {duration1Id, duration1Index}, {duration2Id, duration2Index},
            {duration3Id, duration3Index}, {duration4Id, duration4Index},
            {duration6Id, duration6Index},
    };
    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
    EXPECT_EQ(replacedMetrics, set<int64_t>({duration2Id, duration3Id, duration4Id}));
    // Make sure preserved metrics are the same.
    ASSERT_EQ(newMetricProducers.size(), 5);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(duration1Id)],
              newMetricProducers[newMetricProducerMap.at(duration1Id)]);

    // Make sure replaced metrics are different.
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration2Id)],
              newMetricProducers[newMetricProducerMap.at(duration2Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration3Id)],
              newMetricProducers[newMetricProducerMap.at(duration3Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration4Id)],
              newMetricProducers[newMetricProducerMap.at(duration4Id)]);

    // Verify the conditionToMetricMap. Note that the "what" is not in this map.
    ASSERT_EQ(conditionToMetricMap.size(), 3);
    const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
    EXPECT_THAT(condition2Metrics, UnorderedElementsAre(duration4Index));
    const vector<int>& condition4Metrics = conditionToMetricMap[predicate4Index];
    EXPECT_THAT(condition4Metrics, UnorderedElementsAre(duration1Index));
    const vector<int>& condition5Metrics = conditionToMetricMap[predicate5Index];
    EXPECT_THAT(condition5Metrics, UnorderedElementsAre(duration6Index));

    // Verify the trackerToMetricMap. The start/stop/stopall indices from the "what" should be here.
    ASSERT_EQ(trackerToMetricMap.size(), 8);
    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(duration2Index));
    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(duration2Index));
    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(duration1Index));
    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(duration1Index));
    const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
    EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(duration6Index));
    const vector<int>& matcher6Metrics = trackerToMetricMap[matcher6Index];
    EXPECT_THAT(matcher6Metrics, UnorderedElementsAre(duration6Index));
    const vector<int>& matcher7Metrics = trackerToMetricMap[matcher7Index];
    EXPECT_THAT(matcher7Metrics,
                UnorderedElementsAre(duration1Index, duration3Index, duration4Index));
    const vector<int>& matcher8Metrics = trackerToMetricMap[matcher8Index];
    EXPECT_THAT(matcher8Metrics, UnorderedElementsAre(duration3Index, duration4Index));

    // Verify event activation/deactivation maps.
    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(metricsWithActivation.size(), 0);

    // Verify tracker indices/ids/conditions are correct.
    DurationMetricProducer* durationProducer1 =
            static_cast<DurationMetricProducer*>(newMetricProducers[duration1Index].get());
    EXPECT_EQ(durationProducer1->getMetricId(), duration1Id);
    EXPECT_EQ(durationProducer1->mConditionTrackerIndex, predicate4Index);
    EXPECT_EQ(durationProducer1->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(durationProducer1->mStartIndex, matcher3Index);
    EXPECT_EQ(durationProducer1->mStopIndex, matcher4Index);
    EXPECT_EQ(durationProducer1->mStopAllIndex, matcher7Index);
    EXPECT_EQ(durationProducer1->mCurrentSlicedDurationTrackerMap.size(), 2);
    for (const auto& durationTrackerIt : durationProducer1->mCurrentSlicedDurationTrackerMap) {
        EXPECT_EQ(durationTrackerIt.second->mConditionTrackerIndex, predicate4Index);
    }
    DurationMetricProducer* durationProducer2 =
            static_cast<DurationMetricProducer*>(newMetricProducers[duration2Index].get());
    EXPECT_EQ(durationProducer2->getMetricId(), duration2Id);
    EXPECT_EQ(durationProducer2->mConditionTrackerIndex, -1);
    EXPECT_EQ(durationProducer2->mCondition, ConditionState::kTrue);
    EXPECT_EQ(durationProducer2->mStartIndex, matcher1Index);
    EXPECT_EQ(durationProducer2->mStopIndex, matcher2Index);
    EXPECT_EQ(durationProducer2->mStopAllIndex, -1);
    DurationMetricProducer* durationProducer3 =
            static_cast<DurationMetricProducer*>(newMetricProducers[duration3Index].get());
    EXPECT_EQ(durationProducer3->getMetricId(), duration3Id);
    EXPECT_EQ(durationProducer3->mConditionTrackerIndex, -1);
    EXPECT_EQ(durationProducer3->mCondition, ConditionState::kTrue);
    EXPECT_EQ(durationProducer3->mStartIndex, matcher7Index);
    EXPECT_EQ(durationProducer3->mStopIndex, matcher8Index);
    EXPECT_EQ(durationProducer3->mStopAllIndex, -1);
    DurationMetricProducer* durationProducer4 =
            static_cast<DurationMetricProducer*>(newMetricProducers[duration4Index].get());
    EXPECT_EQ(durationProducer4->getMetricId(), duration4Id);
    EXPECT_EQ(durationProducer4->mConditionTrackerIndex, predicate2Index);
    EXPECT_EQ(durationProducer4->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(durationProducer4->mStartIndex, matcher7Index);
    EXPECT_EQ(durationProducer4->mStopIndex, matcher8Index);
    EXPECT_EQ(durationProducer4->mStopAllIndex, -1);
    DurationMetricProducer* durationProducer6 =
            static_cast<DurationMetricProducer*>(newMetricProducers[duration6Index].get());
    EXPECT_EQ(durationProducer6->getMetricId(), duration6Id);
    EXPECT_EQ(durationProducer6->mConditionTrackerIndex, predicate5Index);
    // TODO(b/167491517): should this be unknown since the condition is sliced?
    EXPECT_EQ(durationProducer6->mCondition, ConditionState::kTrue);
    EXPECT_EQ(durationProducer6->mStartIndex, matcher6Index);
    EXPECT_EQ(durationProducer6->mStopIndex, matcher5Index);
    EXPECT_EQ(durationProducer6->mStopAllIndex, -1);

    sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
    EXPECT_NE(newConditionWizard, oldConditionWizard);
    EXPECT_EQ(newConditionWizard->getStrongCount(), 8);
    oldMetricProducers.clear();
    // Only reference to the old wizard should be the one in the test.
    EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
}

TEST_F(ConfigUpdateTest, TestUpdateValueMetrics) {
    StatsdConfig config;

    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
    int64_t matcher4Id = matcher4.id();
    *config.add_atom_matcher() = matcher4;

    AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
    int64_t matcher5Id = matcher5.id();
    *config.add_atom_matcher() = matcher5;

    Predicate predicate1 = CreateScreenIsOnPredicate();
    int64_t predicate1Id = predicate1.id();
    *config.add_predicate() = predicate1;

    Predicate predicate2 = CreateScreenIsOffPredicate();
    int64_t predicate2Id = predicate2.id();
    *config.add_predicate() = predicate2;

    State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
    int64_t state1Id = state1.id();
    *config.add_state() = state1;

    State state2 = CreateScreenState();
    int64_t state2Id = state2.id();
    *config.add_state() = state2;

    // Add a few value metrics.
    // Note that these will not work as "real" metrics since the value field is always 2.
    // Will be preserved.
    ValueMetric value1 = createValueMetric("VALUE1", matcher4, predicate1Id, {state1Id});
    int64_t value1Id = value1.id();
    *config.add_value_metric() = value1;

    // Will be replaced - definition change.
    ValueMetric value2 = createValueMetric("VALUE2", matcher1, nullopt, {});
    int64_t value2Id = value2.id();
    *config.add_value_metric() = value2;

    // Will be replaced - condition change.
    ValueMetric value3 = createValueMetric("VALUE3", matcher5, predicate2Id, {});
    int64_t value3Id = value3.id();
    *config.add_value_metric() = value3;

    // Will be replaced - state change.
    ValueMetric value4 = createValueMetric("VALUE4", matcher3, nullopt, {state2Id});
    int64_t value4Id = value4.id();
    *config.add_value_metric() = value4;

    // Will be deleted.
    ValueMetric value5 = createValueMetric("VALUE5", matcher2, nullopt, {});
    int64_t value5Id = value5.id();
    *config.add_value_metric() = value5;

    EXPECT_TRUE(initConfig(config));

    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
    sp<EventMatcherWizard> oldMatcherWizard =
            static_cast<ValueMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard;
    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);

    // Change value2, causing it to be replaced.
    value2.set_aggregation_type(ValueMetric::AVG);

    // Mark predicate 2 as replaced. Causes value3 to be replaced.
    set<int64_t> replacedConditions = {predicate2Id};

    // Mark state 2 as replaced. Causes value4 to be replaced.
    set<int64_t> replacedStates = {state2Id};

    // New value metric.
    ValueMetric value6 = createValueMetric("VALUE6", matcher5, predicate1Id, {state1Id});
    int64_t value6Id = value6.id();

    // Map the matchers and predicates in reverse order to force the indices to change.
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    const int matcher5Index = 0;
    newAtomMatchingTrackerMap[matcher5Id] = 0;
    const int matcher4Index = 1;
    newAtomMatchingTrackerMap[matcher4Id] = 1;
    const int matcher3Index = 2;
    newAtomMatchingTrackerMap[matcher3Id] = 2;
    const int matcher2Index = 3;
    newAtomMatchingTrackerMap[matcher2Id] = 3;
    const int matcher1Index = 4;
    newAtomMatchingTrackerMap[matcher1Id] = 4;
    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
                      newAtomMatchingTrackers.begin());

    std::unordered_map<int64_t, int> newConditionTrackerMap;
    const int predicate2Index = 0;
    newConditionTrackerMap[predicate2Id] = 0;
    const int predicate1Index = 1;
    newConditionTrackerMap[predicate1Id] = 1;
    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<ConditionTracker>> newConditionTrackers(2);
    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
                      newConditionTrackers.begin());
    // Say that predicate1 & predicate2 is unknown since the initial condition never changed.
    vector<ConditionState> conditionCache = {ConditionState::kUnknown, ConditionState::kUnknown};

    StatsdConfig newConfig;
    *newConfig.add_value_metric() = value6;
    const int value6Index = 0;
    *newConfig.add_value_metric() = value3;
    const int value3Index = 1;
    *newConfig.add_value_metric() = value1;
    const int value1Index = 2;
    *newConfig.add_value_metric() = value4;
    const int value4Index = 3;
    *newConfig.add_value_metric() = value2;
    const int value2Index = 4;

    *newConfig.add_state() = state1;
    *newConfig.add_state() = state2;

    unordered_map<int64_t, int> stateAtomIdMap;
    unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
    map<int64_t, uint64_t> stateProtoHashes;
    EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));

    // Output data structures to validate.
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
            newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
            oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
            conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    unordered_map<int64_t, int> expectedMetricProducerMap = {
            {value1Id, value1Index}, {value2Id, value2Index}, {value3Id, value3Index},
            {value4Id, value4Index}, {value6Id, value6Index},
    };
    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
    EXPECT_EQ(replacedMetrics, set<int64_t>({value2Id, value3Id, value4Id}));

    // Make sure preserved metrics are the same.
    ASSERT_EQ(newMetricProducers.size(), 5);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(value1Id)],
              newMetricProducers[newMetricProducerMap.at(value1Id)]);

    // Make sure replaced metrics are different.
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value2Id)],
              newMetricProducers[newMetricProducerMap.at(value2Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value3Id)],
              newMetricProducers[newMetricProducerMap.at(value3Id)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value4Id)],
              newMetricProducers[newMetricProducerMap.at(value4Id)]);

    // Verify the conditionToMetricMap.
    ASSERT_EQ(conditionToMetricMap.size(), 2);
    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
    EXPECT_THAT(condition1Metrics, UnorderedElementsAre(value1Index, value6Index));
    const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
    EXPECT_THAT(condition2Metrics, UnorderedElementsAre(value3Index));

    // Verify the trackerToMetricMap.
    ASSERT_EQ(trackerToMetricMap.size(), 4);
    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(value2Index));
    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(value4Index));
    const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
    EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(value1Index));
    const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
    EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(value3Index, value6Index));

    // Verify event activation/deactivation maps.
    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(metricsWithActivation.size(), 0);

    // Verify tracker indices/ids/conditions/states are correct.
    ValueMetricProducer* valueProducer1 =
            static_cast<ValueMetricProducer*>(newMetricProducers[value1Index].get());
    EXPECT_EQ(valueProducer1->getMetricId(), value1Id);
    EXPECT_EQ(valueProducer1->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(valueProducer1->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(valueProducer1->mWhatMatcherIndex, matcher4Index);
    ValueMetricProducer* valueProducer2 =
            static_cast<ValueMetricProducer*>(newMetricProducers[value2Index].get());
    EXPECT_EQ(valueProducer2->getMetricId(), value2Id);
    EXPECT_EQ(valueProducer2->mConditionTrackerIndex, -1);
    EXPECT_EQ(valueProducer2->mCondition, ConditionState::kTrue);
    EXPECT_EQ(valueProducer2->mWhatMatcherIndex, matcher1Index);
    ValueMetricProducer* valueProducer3 =
            static_cast<ValueMetricProducer*>(newMetricProducers[value3Index].get());
    EXPECT_EQ(valueProducer3->getMetricId(), value3Id);
    EXPECT_EQ(valueProducer3->mConditionTrackerIndex, predicate2Index);
    EXPECT_EQ(valueProducer3->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(valueProducer3->mWhatMatcherIndex, matcher5Index);
    ValueMetricProducer* valueProducer4 =
            static_cast<ValueMetricProducer*>(newMetricProducers[value4Index].get());
    EXPECT_EQ(valueProducer4->getMetricId(), value4Id);
    EXPECT_EQ(valueProducer4->mConditionTrackerIndex, -1);
    EXPECT_EQ(valueProducer4->mCondition, ConditionState::kTrue);
    EXPECT_EQ(valueProducer4->mWhatMatcherIndex, matcher3Index);
    ValueMetricProducer* valueProducer6 =
            static_cast<ValueMetricProducer*>(newMetricProducers[value6Index].get());
    EXPECT_EQ(valueProducer6->getMetricId(), value6Id);
    EXPECT_EQ(valueProducer6->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(valueProducer6->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(valueProducer6->mWhatMatcherIndex, matcher5Index);

    sp<EventMatcherWizard> newMatcherWizard = valueProducer1->mEventMatcherWizard;
    EXPECT_NE(newMatcherWizard, oldMatcherWizard);
    EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
    oldMetricProducers.clear();
    // Only reference to the old wizard should be the one in the test.
    EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
}

TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) {
    StatsdConfig config;
    // Add atom matchers
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
    int64_t matcher4Id = matcher4.id();
    *config.add_atom_matcher() = matcher4;

    // Add an event metric with multiple activations.
    EventMetric event1 = createEventMetric("EVENT1", matcher1Id, nullopt);
    int64_t event1Id = event1.id();
    *config.add_event_metric() = event1;

    int64_t matcher2TtlSec = 2, matcher3TtlSec = 3, matcher4TtlSec = 4;
    MetricActivation metricActivation;
    metricActivation.set_metric_id(event1Id);
    EventActivation* activation = metricActivation.add_event_activation();
    activation->set_atom_matcher_id(matcher2Id);
    activation->set_ttl_seconds(matcher2TtlSec);
    activation->set_activation_type(ACTIVATE_IMMEDIATELY);
    activation->set_deactivation_atom_matcher_id(matcher1Id);
    activation = metricActivation.add_event_activation();
    activation->set_atom_matcher_id(matcher3Id);
    activation->set_ttl_seconds(matcher3TtlSec);
    activation->set_activation_type(ACTIVATE_ON_BOOT);
    activation->set_deactivation_atom_matcher_id(matcher1Id);
    activation = metricActivation.add_event_activation();
    activation->set_atom_matcher_id(matcher4Id);
    activation->set_ttl_seconds(matcher4TtlSec);
    activation->set_activation_type(ACTIVATE_IMMEDIATELY);
    activation->set_deactivation_atom_matcher_id(matcher2Id);
    *config.add_metric_activation() = metricActivation;

    EXPECT_TRUE(initConfig(config));

    // Activate some of the event activations.
    ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
    int64_t matcher2StartNs = 12345;
    oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher2Id], matcher2StartNs);
    int64_t matcher3StartNs = 23456;
    oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher3Id], matcher3StartNs);
    EXPECT_TRUE(oldMetricProducers[0]->isActive());

    // Map the matchers and predicates in reverse order to force the indices to change.
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    const int matcher4Index = 0;
    newAtomMatchingTrackerMap[matcher4Id] = 0;
    const int matcher3Index = 1;
    newAtomMatchingTrackerMap[matcher3Id] = 1;
    const int matcher2Index = 2;
    newAtomMatchingTrackerMap[matcher2Id] = 2;
    const int matcher1Index = 3;
    newAtomMatchingTrackerMap[matcher1Id] = 3;
    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(4);
    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
                      newAtomMatchingTrackers.begin());
    set<int64_t> replacedMatchers;

    unordered_map<int64_t, int> newConditionTrackerMap;
    vector<sp<ConditionTracker>> newConditionTrackers;
    set<int64_t> replacedConditions;
    vector<ConditionState> conditionCache;
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
            newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
            newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    // Verify event activation/deactivation maps.
    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 3);
    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher3Index], UnorderedElementsAre(0));
    EXPECT_THAT(activationAtomTrackerToMetricMap[matcher4Index], UnorderedElementsAre(0));
    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 2);
    EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher1Index], UnorderedElementsAre(0, 0));
    EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
    ASSERT_EQ(metricsWithActivation.size(), 1);
    EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(0));

    // Verify mEventActivation and mEventDeactivation map of the producer.
    sp<MetricProducer> producer = newMetricProducers[0];
    EXPECT_TRUE(producer->isActive());
    ASSERT_EQ(producer->mEventActivationMap.size(), 3);
    shared_ptr<Activation> matcher2Activation = producer->mEventActivationMap[matcher2Index];
    EXPECT_EQ(matcher2Activation->ttl_ns, matcher2TtlSec * NS_PER_SEC);
    EXPECT_EQ(matcher2Activation->activationType, ACTIVATE_IMMEDIATELY);
    EXPECT_EQ(matcher2Activation->state, kActive);
    EXPECT_EQ(matcher2Activation->start_ns, matcher2StartNs);
    shared_ptr<Activation> matcher3Activation = producer->mEventActivationMap[matcher3Index];
    EXPECT_EQ(matcher3Activation->ttl_ns, matcher3TtlSec * NS_PER_SEC);
    EXPECT_EQ(matcher3Activation->activationType, ACTIVATE_ON_BOOT);
    EXPECT_EQ(matcher3Activation->state, kActiveOnBoot);
    shared_ptr<Activation> matcher4Activation = producer->mEventActivationMap[matcher4Index];
    EXPECT_EQ(matcher4Activation->ttl_ns, matcher4TtlSec * NS_PER_SEC);
    EXPECT_EQ(matcher4Activation->activationType, ACTIVATE_IMMEDIATELY);
    EXPECT_EQ(matcher4Activation->state, kNotActive);

    ASSERT_EQ(producer->mEventDeactivationMap.size(), 2);
    EXPECT_THAT(producer->mEventDeactivationMap[matcher1Index],
                UnorderedElementsAre(matcher2Activation, matcher3Activation));
    EXPECT_THAT(producer->mEventDeactivationMap[matcher2Index],
                UnorderedElementsAre(matcher4Activation));
}

TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) {
    StatsdConfig config;
    // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig
    AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
    int64_t matcher1Id = matcher1.id();
    *config.add_atom_matcher() = matcher1;

    AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
    int64_t matcher2Id = matcher2.id();
    *config.add_atom_matcher() = matcher2;

    AtomMatcher matcher3 = CreateTemperatureAtomMatcher();
    int64_t matcher3Id = matcher3.id();
    *config.add_atom_matcher() = matcher3;

    Predicate predicate1 = CreateScreenIsOnPredicate();
    int64_t predicate1Id = predicate1.id();
    *config.add_predicate() = predicate1;

    // Add a few count metrics.
    // Will be preserved.
    CountMetric countMetric = createCountMetric("COUNT1", matcher1Id, predicate1Id, {});
    int64_t countMetricId = countMetric.id();
    *config.add_count_metric() = countMetric;

    // Will be replaced since matcher2 is replaced.
    EventMetric eventMetric = createEventMetric("EVENT1", matcher2Id, nullopt);
    int64_t eventMetricId = eventMetric.id();
    *config.add_event_metric() = eventMetric;

    // Will be replaced because the definition changes - a predicate is added.
    GaugeMetric gaugeMetric = createGaugeMetric("GAUGE1", matcher3Id,
                                                GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
    int64_t gaugeMetricId = gaugeMetric.id();
    *config.add_gauge_metric() = gaugeMetric;

    // Preserved.
    ValueMetric valueMetric = createValueMetric("VALUE1", matcher3, predicate1Id, {});
    int64_t valueMetricId = valueMetric.id();
    *config.add_value_metric() = valueMetric;

    // Preserved.
    DurationMetric durationMetric = createDurationMetric("DURATION1", predicate1Id, nullopt, {});
    int64_t durationMetricId = durationMetric.id();
    *config.add_duration_metric() = durationMetric;

    EXPECT_TRUE(initConfig(config));

    // Used later to ensure the condition wizard is replaced. Get it before doing the update.
    sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
    EXPECT_EQ(oldConditionWizard->getStrongCount(), 6);

    // Mark matcher 2 as replaced. Causes eventMetric to be replaced.
    set<int64_t> replacedMatchers;
    replacedMatchers.insert(matcher2Id);

    // Add predicate1 as a predicate on gaugeMetric, causing it to be replaced.
    gaugeMetric.set_condition(predicate1Id);

    // Map the matchers and predicates in reverse order to force the indices to change.
    std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
    const int matcher3Index = 0;
    newAtomMatchingTrackerMap[matcher3Id] = 0;
    const int matcher2Index = 1;
    newAtomMatchingTrackerMap[matcher2Id] = 1;
    const int matcher1Index = 2;
    newAtomMatchingTrackerMap[matcher1Id] = 2;
    // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(3);
    std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
                      newAtomMatchingTrackers.begin());

    std::unordered_map<int64_t, int> newConditionTrackerMap;
    const int predicate1Index = 0;
    newConditionTrackerMap[predicate1Id] = 0;
    // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
    vector<sp<ConditionTracker>> newConditionTrackers(1);
    std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
                      newConditionTrackers.begin());
    vector<ConditionState> conditionCache = {ConditionState::kUnknown};

    // The order matters. we parse in the order of: count, duration, event, value, gauge.
    StatsdConfig newConfig;
    *newConfig.add_count_metric() = countMetric;
    const int countMetricIndex = 0;
    *newConfig.add_duration_metric() = durationMetric;
    const int durationMetricIndex = 1;
    *newConfig.add_event_metric() = eventMetric;
    const int eventMetricIndex = 2;
    *newConfig.add_value_metric() = valueMetric;
    const int valueMetricIndex = 3;
    *newConfig.add_gauge_metric() = gaugeMetric;
    const int gaugeMetricIndex = 4;

    // Add the predicate since duration metric needs it.
    *newConfig.add_predicate() = predicate1;

    // Output data structures to validate.
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
            newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
            newConditionTrackers, conditionCache, /*stateAtomIdMap*/ {}, /*allStateGroupMaps=*/{},
            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    unordered_map<int64_t, int> expectedMetricProducerMap = {
            {countMetricId, countMetricIndex}, {durationMetricId, durationMetricIndex},
            {eventMetricId, eventMetricIndex}, {valueMetricId, valueMetricIndex},
            {gaugeMetricId, gaugeMetricIndex},
    };
    EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));

    EXPECT_EQ(replacedMetrics, set<int64_t>({eventMetricId, gaugeMetricId}));

    // Make sure preserved metrics are the same.
    ASSERT_EQ(newMetricProducers.size(), 5);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(countMetricId)],
              newMetricProducers[newMetricProducerMap.at(countMetricId)]);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(durationMetricId)],
              newMetricProducers[newMetricProducerMap.at(durationMetricId)]);
    EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(valueMetricId)],
              newMetricProducers[newMetricProducerMap.at(valueMetricId)]);

    // Make sure replaced metrics are different.
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(eventMetricId)],
              newMetricProducers[newMetricProducerMap.at(eventMetricId)]);
    EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gaugeMetricId)],
              newMetricProducers[newMetricProducerMap.at(gaugeMetricId)]);

    // Verify the conditionToMetricMap.
    ASSERT_EQ(conditionToMetricMap.size(), 1);
    const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
    EXPECT_THAT(condition1Metrics,
                UnorderedElementsAre(countMetricIndex, gaugeMetricIndex, valueMetricIndex));

    // Verify the trackerToMetricMap.
    ASSERT_EQ(trackerToMetricMap.size(), 3);
    const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
    EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(countMetricIndex, durationMetricIndex));
    const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
    EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(eventMetricIndex, durationMetricIndex));
    const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
    EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gaugeMetricIndex, valueMetricIndex));

    // Verify event activation/deactivation maps.
    ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
    ASSERT_EQ(metricsWithActivation.size(), 0);

    // Verify tracker indices/ids/conditions are correct.
    EXPECT_EQ(newMetricProducers[countMetricIndex]->getMetricId(), countMetricId);
    EXPECT_EQ(newMetricProducers[countMetricIndex]->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(newMetricProducers[countMetricIndex]->mCondition, ConditionState::kUnknown);
    EXPECT_EQ(newMetricProducers[durationMetricIndex]->getMetricId(), durationMetricId);
    EXPECT_EQ(newMetricProducers[durationMetricIndex]->mConditionTrackerIndex, -1);
    EXPECT_EQ(newMetricProducers[durationMetricIndex]->mCondition, ConditionState::kTrue);
    EXPECT_EQ(newMetricProducers[eventMetricIndex]->getMetricId(), eventMetricId);
    EXPECT_EQ(newMetricProducers[eventMetricIndex]->mConditionTrackerIndex, -1);
    EXPECT_EQ(newMetricProducers[eventMetricIndex]->mCondition, ConditionState::kTrue);
    EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->getMetricId(), gaugeMetricId);
    EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mConditionTrackerIndex, predicate1Index);
    EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mCondition, ConditionState::kUnknown);

    sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
    EXPECT_NE(newConditionWizard, oldConditionWizard);
    EXPECT_EQ(newConditionWizard->getStrongCount(), 6);
    oldMetricProducers.clear();
    // Only reference to the old wizard should be the one in the test.
    EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
}

TEST_F(ConfigUpdateTest, TestAlertPreserve) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});

    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
    *config.add_alert() = alert;
    EXPECT_TRUE(initConfig(config));

    UpdateStatus updateStatus = UPDATE_UNKNOWN;
    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
                                           /*replacedMetrics*/ {}, updateStatus));
    EXPECT_EQ(updateStatus, UPDATE_PRESERVE);
}

TEST_F(ConfigUpdateTest, TestAlertMetricChanged) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    CountMetric metric = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
    *config.add_count_metric() = metric;

    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
    *config.add_alert() = alert;
    EXPECT_TRUE(initConfig(config));

    UpdateStatus updateStatus = UPDATE_UNKNOWN;
    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
                                           /*replacedMetrics*/ {metric.id()}, updateStatus));
    EXPECT_EQ(updateStatus, UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestAlertDefinitionChanged) {
    StatsdConfig config;
    AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
    *config.add_atom_matcher() = whatMatcher;

    *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});

    Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
    *config.add_alert() = alert;
    EXPECT_TRUE(initConfig(config));

    alert.set_num_buckets(2);

    UpdateStatus updateStatus = UPDATE_UNKNOWN;
    EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
                                           /*replacedMetrics*/ {}, updateStatus));
    EXPECT_EQ(updateStatus, UPDATE_REPLACE);
}

TEST_F(ConfigUpdateTest, TestUpdateAlerts) {
    StatsdConfig config;
    // Add atom matchers/predicates/metrics. These are mostly needed for initStatsdConfig
    *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
    *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
    *config.add_predicate() = CreateScreenIsOnPredicate();

    CountMetric countMetric = createCountMetric("COUNT1", config.atom_matcher(0).id(), nullopt, {});
    int64_t countMetricId = countMetric.id();
    *config.add_count_metric() = countMetric;

    DurationMetric durationMetric =
            createDurationMetric("DURATION1", config.predicate(0).id(), nullopt, {});
    int64_t durationMetricId = durationMetric.id();
    *config.add_duration_metric() = durationMetric;

    // Add alerts.
    // Preserved.
    Alert alert1 = createAlert("Alert1", durationMetricId, /*buckets*/ 1, /*triggerSum*/ 5000);
    int64_t alert1Id = alert1.id();
    *config.add_alert() = alert1;

    // Replaced.
    Alert alert2 = createAlert("Alert2", countMetricId, /*buckets*/ 1, /*triggerSum*/ 2);
    int64_t alert2Id = alert2.id();
    *config.add_alert() = alert2;

    // Replaced.
    Alert alert3 = createAlert("Alert3", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 5000);
    int64_t alert3Id = alert3.id();
    *config.add_alert() = alert3;

    // Add Subscriptions.
    Subscription subscription1 = createSubscription("S1", Subscription::ALERT, alert1Id);
    *config.add_subscription() = subscription1;
    Subscription subscription2 = createSubscription("S2", Subscription::ALERT, alert1Id);
    *config.add_subscription() = subscription2;
    Subscription subscription3 = createSubscription("S3", Subscription::ALERT, alert2Id);
    *config.add_subscription() = subscription3;

    EXPECT_TRUE(initConfig(config));

    // Add a duration tracker to the duration metric to ensure durationTrackers are updated
    // with the proper anomalyTrackers.
    unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
            timeBaseNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
    oldMetricProducers[1]->onMatchedLogEvent(0, *event.get());

    // Change the count metric. Causes alert2 to be replaced.
    config.mutable_count_metric(0)->set_bucket(ONE_DAY);
    // Change num buckets on alert3, causing replacement.
    alert3.set_num_buckets(5);

    // New alert.
    Alert alert4 = createAlert("Alert4", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 10000);
    int64_t alert4Id = alert4.id();

    // Move subscription2 to be on alert2 and make a new subscription.
    subscription2.set_rule_id(alert2Id);
    Subscription subscription4 = createSubscription("S4", Subscription::ALERT, alert2Id);

    // Create the new config. Modify the old one to avoid adding the matchers/predicates.
    // Add alerts in different order so the map is changed.
    config.clear_alert();
    *config.add_alert() = alert4;
    const int alert4Index = 0;
    *config.add_alert() = alert3;
    const int alert3Index = 1;
    *config.add_alert() = alert1;
    const int alert1Index = 2;
    *config.add_alert() = alert2;
    const int alert2Index = 3;

    // Subscription3 is removed.
    config.clear_subscription();
    *config.add_subscription() = subscription4;
    *config.add_subscription() = subscription2;
    *config.add_subscription() = subscription1;

    // Output data structures from update metrics. Don't care about the outputs besides
    // replacedMetrics, but need to do this so that the metrics clear their anomaly trackers.
    unordered_map<int64_t, int> newMetricProducerMap;
    vector<sp<MetricProducer>> newMetricProducers;
    unordered_map<int, vector<int>> conditionToMetricMap;
    unordered_map<int, vector<int>> trackerToMetricMap;
    set<int64_t> noReportMetricIds;
    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
    vector<int> metricsWithActivation;
    set<int64_t> replacedMetrics;
    EXPECT_TRUE(updateMetrics(
            key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
            oldAtomMatchingTrackerMap, oldAtomMatchingTrackerMap, /*replacedMatchers*/ {},
            oldAtomMatchingTrackers, oldConditionTrackerMap, /*replacedConditions=*/{},
            oldConditionTrackers, {ConditionState::kUnknown}, /*stateAtomIdMap*/ {},
            /*allStateGroupMaps=*/{},
            /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
            newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
            activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
            metricsWithActivation, replacedMetrics));

    EXPECT_EQ(replacedMetrics, set<int64_t>({countMetricId}));

    unordered_map<int64_t, int> newAlertTrackerMap;
    vector<sp<AnomalyTracker>> newAnomalyTrackers;
    EXPECT_TRUE(updateAlerts(config, newMetricProducerMap, replacedMetrics, oldAlertTrackerMap,
                             oldAnomalyTrackers, anomalyAlarmMonitor, newMetricProducers,
                             newAlertTrackerMap, newAnomalyTrackers));

    unordered_map<int64_t, int> expectedAlertMap = {
            {alert1Id, alert1Index},
            {alert2Id, alert2Index},
            {alert3Id, alert3Index},
            {alert4Id, alert4Index},
    };
    EXPECT_THAT(newAlertTrackerMap, ContainerEq(expectedAlertMap));

    // Make sure preserved alerts are the same.
    ASSERT_EQ(newAnomalyTrackers.size(), 4);
    EXPECT_EQ(oldAnomalyTrackers[oldAlertTrackerMap.at(alert1Id)],
              newAnomalyTrackers[newAlertTrackerMap.at(alert1Id)]);

    // Make sure replaced alerts are different.
    EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert2Id)],
              newAnomalyTrackers[newAlertTrackerMap.at(alert2Id)]);
    EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert3Id)],
              newAnomalyTrackers[newAlertTrackerMap.at(alert3Id)]);

    // Verify the alerts have the correct anomaly trackers.
    ASSERT_EQ(newMetricProducers.size(), 2);
    EXPECT_THAT(newMetricProducers[0]->mAnomalyTrackers,
                UnorderedElementsAre(newAnomalyTrackers[alert2Index]));
    // For durationMetric, make sure the duration trackers get the updated anomalyTrackers.
    DurationMetricProducer* durationProducer =
            static_cast<DurationMetricProducer*>(newMetricProducers[1].get());
    EXPECT_THAT(
            durationProducer->mAnomalyTrackers,
            UnorderedElementsAre(newAnomalyTrackers[alert1Index], newAnomalyTrackers[alert3Index],
                                 newAnomalyTrackers[alert4Index]));
    ASSERT_EQ(durationProducer->mCurrentSlicedDurationTrackerMap.size(), 1);
    for (const auto& durationTrackerIt : durationProducer->mCurrentSlicedDurationTrackerMap) {
        EXPECT_EQ(durationTrackerIt.second->mAnomalyTrackers, durationProducer->mAnomalyTrackers);
    }

    // Verify alerts have the correct subscriptions. Use subscription id as proxy for equivalency.
    vector<int64_t> alert1Subscriptions;
    for (const Subscription& subscription : newAnomalyTrackers[alert1Index]->mSubscriptions) {
        alert1Subscriptions.push_back(subscription.id());
    }
    EXPECT_THAT(alert1Subscriptions, UnorderedElementsAre(subscription1.id()));
    vector<int64_t> alert2Subscriptions;
    for (const Subscription& subscription : newAnomalyTrackers[alert2Index]->mSubscriptions) {
        alert2Subscriptions.push_back(subscription.id());
    }
    EXPECT_THAT(alert2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription4.id()));
    EXPECT_THAT(newAnomalyTrackers[alert3Index]->mSubscriptions, IsEmpty());
    EXPECT_THAT(newAnomalyTrackers[alert4Index]->mSubscriptions, IsEmpty());
}

TEST_F(ConfigUpdateTest, TestUpdateAlarms) {
    StatsdConfig config;
    // Add alarms.
    Alarm alarm1 = createAlarm("Alarm1", /*offset*/ 1 * MS_PER_SEC, /*period*/ 50 * MS_PER_SEC);
    int64_t alarm1Id = alarm1.id();
    *config.add_alarm() = alarm1;

    Alarm alarm2 = createAlarm("Alarm2", /*offset*/ 1 * MS_PER_SEC, /*period*/ 2000 * MS_PER_SEC);
    int64_t alarm2Id = alarm2.id();
    *config.add_alarm() = alarm2;

    Alarm alarm3 = createAlarm("Alarm3", /*offset*/ 10 * MS_PER_SEC, /*period*/ 5000 * MS_PER_SEC);
    int64_t alarm3Id = alarm3.id();
    *config.add_alarm() = alarm3;

    // Add Subscriptions.
    Subscription subscription1 = createSubscription("S1", Subscription::ALARM, alarm1Id);
    *config.add_subscription() = subscription1;
    Subscription subscription2 = createSubscription("S2", Subscription::ALARM, alarm1Id);
    *config.add_subscription() = subscription2;
    Subscription subscription3 = createSubscription("S3", Subscription::ALARM, alarm2Id);
    *config.add_subscription() = subscription3;

    EXPECT_TRUE(initConfig(config));

    ASSERT_EQ(oldAlarmTrackers.size(), 3);
    // Config is created at statsd start time, so just add the offsets.
    EXPECT_EQ(oldAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
    EXPECT_EQ(oldAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
    EXPECT_EQ(oldAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);

    // Change alarm2/alarm3.
    config.mutable_alarm(1)->set_offset_millis(5 * MS_PER_SEC);
    config.mutable_alarm(2)->set_period_millis(10000 * MS_PER_SEC);

    // Move subscription2 to be on alarm2 and make a new subscription.
    config.mutable_subscription(1)->set_rule_id(alarm2Id);
    Subscription subscription4 = createSubscription("S4", Subscription::ALARM, alarm1Id);
    *config.add_subscription() = subscription4;

    // Update time is 2 seconds after the base time.
    int64_t currentTimeNs = timeBaseNs + 2 * NS_PER_SEC;
    vector<sp<AlarmTracker>> newAlarmTrackers;
    EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
                           newAlarmTrackers));

    ASSERT_EQ(newAlarmTrackers.size(), 3);
    // Config is updated 2 seconds after statsd start
    // The offset has passed for alarm1, but not for alarms 2/3.
    EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 50);
    EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5);
    EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);

    // Verify alarms have the correct subscriptions. Use subscription id as proxy for equivalency.
    vector<int64_t> alarm1Subscriptions;
    for (const Subscription& subscription : newAlarmTrackers[0]->mSubscriptions) {
        alarm1Subscriptions.push_back(subscription.id());
    }
    EXPECT_THAT(alarm1Subscriptions, UnorderedElementsAre(subscription1.id(), subscription4.id()));
    vector<int64_t> alarm2Subscriptions;
    for (const Subscription& subscription : newAlarmTrackers[1]->mSubscriptions) {
        alarm2Subscriptions.push_back(subscription.id());
    }
    EXPECT_THAT(alarm2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription3.id()));
    EXPECT_THAT(newAlarmTrackers[2]->mSubscriptions, IsEmpty());

    // Verify the alarm monitor is updated accordingly once the old alarms are removed.
    // Alarm2 fires the earliest.
    oldAlarmTrackers.clear();
    EXPECT_EQ(periodicAlarmMonitor->getRegisteredAlarmTimeSec(), timeBaseNs / NS_PER_SEC + 5);

    // Do another update 60 seconds after config creation time, after the offsets of each alarm.
    currentTimeNs = timeBaseNs + 60 * NS_PER_SEC;
    newAlarmTrackers.clear();
    EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
                           newAlarmTrackers));

    ASSERT_EQ(newAlarmTrackers.size(), 3);
    // Config is updated one minute after statsd start.
    // Two periods have passed for alarm 1, one has passed for alarms2/3.
    EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 2 * 50);
    EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5 + 2000);
    EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10 + 10000);
}

}  // namespace statsd
}  // namespace os
}  // namespace android

#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
