Expose the list of remapped channels from LogReader

This helps us track more reliably which channels are remapped and which
aren't for any applications which automatically find channels.

Change-Id: Iae344bc613f53e15afac7a33d5c766defcb09ee6
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/aos/events/logging/log_reader.cc b/aos/events/logging/log_reader.cc
index 169311e..d6213ae 100644
--- a/aos/events/logging/log_reader.cc
+++ b/aos/events/logging/log_reader.cc
@@ -49,6 +49,24 @@
 namespace logger {
 namespace {
 
+bool CompareChannels(const Channel *c,
+                     ::std::pair<std::string_view, std::string_view> p) {
+  int name_compare = c->name()->string_view().compare(p.first);
+  if (name_compare == 0) {
+    return c->type()->string_view() < p.second;
+  } else if (name_compare < 0) {
+    return true;
+  } else {
+    return false;
+  }
+}
+
+bool EqualsChannels(const Channel *c,
+                    ::std::pair<std::string_view, std::string_view> p) {
+  return c->name()->string_view() == p.first &&
+         c->type()->string_view() == p.second;
+}
+
 // Copies the channel, removing the schema as we go.  If new_name is provided,
 // it is used instead of the name inside the channel.  If new_type is provided,
 // it is used instead of the type in the channel.
@@ -1231,6 +1249,30 @@
   // TODO(austin): Lazily re-build to save CPU?
 }
 
+std::vector<const Channel *> LogReader::RemappedChannels() const {
+  std::vector<const Channel *> result;
+  result.reserve(remapped_channels_.size());
+  for (auto &pair : remapped_channels_) {
+    const Channel *const logged_channel =
+        CHECK_NOTNULL(logged_configuration()->channels()->Get(pair.first));
+
+    auto channel_iterator = std::lower_bound(
+        remapped_configuration_->channels()->cbegin(),
+        remapped_configuration_->channels()->cend(),
+        std::make_pair(std::string_view(pair.second.remapped_name),
+                       logged_channel->type()->string_view()),
+        CompareChannels);
+
+    CHECK(channel_iterator != remapped_configuration_->channels()->cend());
+    CHECK(EqualsChannels(
+        *channel_iterator,
+        std::make_pair(std::string_view(pair.second.remapped_name),
+                       logged_channel->type()->string_view())));
+    result.push_back(*channel_iterator);
+  }
+  return result;
+}
+
 const Channel *LogReader::RemapChannel(const EventLoop *event_loop,
                                        const Node *node,
                                        const Channel *channel) {
diff --git a/aos/events/logging/log_reader.h b/aos/events/logging/log_reader.h
index 8293956..5dfaeea 100644
--- a/aos/events/logging/log_reader.h
+++ b/aos/events/logging/log_reader.h
@@ -173,6 +173,9 @@
     return channel->logger() != LoggerConfig::NOT_LOGGED;
   }
 
+  // Returns a list of all the original channels from remapping.
+  std::vector<const Channel *> RemappedChannels() const;
+
   SimulatedEventLoopFactory *event_loop_factory() {
     return event_loop_factory_;
   }
diff --git a/aos/events/logging/logger_test.cc b/aos/events/logging/logger_test.cc
index 8d8a2a6..77333d6 100644
--- a/aos/events/logging/logger_test.cc
+++ b/aos/events/logging/logger_test.cc
@@ -1774,6 +1774,11 @@
   SimulatedEventLoopFactory log_reader_factory(reader.configuration());
   log_reader_factory.set_send_delay(chrono::microseconds(0));
 
+  std::vector<const Channel *> remapped_channels = reader.RemappedChannels();
+  ASSERT_EQ(remapped_channels.size(), 1u);
+  EXPECT_EQ(remapped_channels[0]->name()->string_view(), "/original/pi1/aos");
+  EXPECT_EQ(remapped_channels[0]->type()->string_view(), "aos.timing.Report");
+
   reader.Register(&log_reader_factory);
 
   const Node *pi1 =