buffet: Restructure buffet_client.cc

This makes it more obvious at a glance what magic strings correspond to
commands and moves the argument parsing into each method.  It also stops
us from passing the Bus around by making it a class variable.

BUG=None
TEST=buffet_client TestMethod and UpdateState still work.

Change-Id: I36fad6ea69320aba5c98a21f85fa90b872dc7519
Reviewed-on: https://chromium-review.googlesource.com/198927
Tested-by: Christopher Wiley <wiley@chromium.org>
Reviewed-by: Chris Sosa <sosa@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Commit-Queue: Christopher Wiley <wiley@chromium.org>
diff --git a/buffet/buffet_client.cc b/buffet/buffet_client.cc
index f351040..16bbbb2 100644
--- a/buffet/buffet_client.cc
+++ b/buffet/buffet_client.cc
@@ -4,15 +4,16 @@
 
 #include <iostream>
 #include <string>
+#include <sysexits.h>
 
 #include <base/command_line.h>
 #include <base/logging.h>
+#include <base/memory/ref_counted.h>
 #include <base/memory/scoped_ptr.h>
 #include <base/values.h>
 #include <dbus/bus.h>
-#include <dbus/object_proxy.h>
 #include <dbus/message.h>
-#include <sysexits.h>
+#include <dbus/object_proxy.h>
 #include <dbus/values_util.h>
 
 #include "buffet/dbus_constants.h"
@@ -23,158 +24,6 @@
 namespace {
 static const int default_timeout_ms = 1000;
 
-dbus::ObjectProxy* GetBuffetDBusProxy(dbus::Bus *bus,
-                                      const std::string& object_path) {
-  return bus->GetObjectProxy(
-      buffet::dbus_constants::kServiceName,
-      dbus::ObjectPath(object_path));
-}
-
-bool CallTestMethod(dbus::ObjectProxy* proxy) {
-  dbus::MethodCall method_call(buffet::dbus_constants::kManagerInterface,
-                               buffet::dbus_constants::kManagerTestMethod);
-  scoped_ptr<dbus::Response> response(
-    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
-  if (!response) {
-    std::cout << "Failed to receive a response." << std::endl;
-    return false;
-  }
-  std::cout << "Received a response." << std::endl;
-  return true;
-}
-
-bool CallManagerCheckDeviceRegistered(dbus::ObjectProxy* proxy) {
-  dbus::MethodCall method_call(
-    buffet::dbus_constants::kManagerInterface,
-    buffet::dbus_constants::kManagerCheckDeviceRegistered);
-
-  scoped_ptr<dbus::Response> response(
-    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
-  if (!response) {
-    std::cout << "Failed to receive a response." << std::endl;
-    return false;
-  }
-
-  dbus::MessageReader reader(response.get());
-  std::string device_id;
-  if (!reader.PopString(&device_id)) {
-    std::cout << "No device ID in response." << std::endl;
-    return false;
-  }
-
-  std::cout << "Device ID: "
-            << (device_id.empty() ? std::string("<unregistered>") : device_id)
-            << std::endl;
-  return true;
-}
-
-bool CallManagerGetDeviceInfo(dbus::ObjectProxy* proxy) {
-  dbus::MethodCall method_call(
-    buffet::dbus_constants::kManagerInterface,
-    buffet::dbus_constants::kManagerGetDeviceInfo);
-
-  scoped_ptr<dbus::Response> response(
-    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
-  if (!response) {
-    std::cout << "Failed to receive a response." << std::endl;
-    return false;
-  }
-
-  dbus::MessageReader reader(response.get());
-  std::string device_info;
-  if (!reader.PopString(&device_info)) {
-    std::cout << "No device info in response." << std::endl;
-    return false;
-  }
-
-  std::cout << "Device Info: "
-    << (device_info.empty() ? std::string("<unregistered>") : device_info)
-    << std::endl;
-  return true;
-}
-
-bool CallManagerStartRegisterDevice(
-    dbus::ObjectProxy* proxy,
-    const std::map<std::string, std::shared_ptr<base::Value>>& params) {
-  dbus::MethodCall method_call(
-      buffet::dbus_constants::kManagerInterface,
-      buffet::dbus_constants::kManagerStartRegisterDevice);
-  dbus::MessageWriter writer(&method_call);
-  dbus::MessageWriter dict_writer(nullptr);
-  writer.OpenArray("{sv}", &dict_writer);
-  for (auto&& pair : params) {
-    dbus::MessageWriter dict_entry_writer(nullptr);
-    dict_writer.OpenDictEntry(&dict_entry_writer);
-    dict_entry_writer.AppendString(pair.first);
-    dbus::AppendBasicTypeValueDataAsVariant(&dict_entry_writer,
-                                            *pair.second.get());
-    dict_writer.CloseContainer(&dict_entry_writer);
-  }
-  writer.CloseContainer(&dict_writer);
-
-  static const int timeout_ms = 3000;
-  scoped_ptr<dbus::Response> response(
-    proxy->CallMethodAndBlock(&method_call, timeout_ms));
-  if (!response) {
-    std::cout << "Failed to receive a response." << std::endl;
-    return false;
-  }
-
-  dbus::MessageReader reader(response.get());
-  std::string info;
-  if (!reader.PopString(&info)) {
-    std::cout << "No valid response." << std::endl;
-    return false;
-  }
-
-  std::cout << "Registration started: " << info << std::endl;
-  return true;
-}
-
-bool CallManagerFinishRegisterDevice(dbus::ObjectProxy* proxy,
-                                     const std::string& user_auth_code) {
-  dbus::MethodCall method_call(
-    buffet::dbus_constants::kManagerInterface,
-    buffet::dbus_constants::kManagerFinishRegisterDevice);
-  dbus::MessageWriter writer(&method_call);
-  writer.AppendString(user_auth_code);
-  static const int timeout_ms = 10000;
-  scoped_ptr<dbus::Response> response(
-    proxy->CallMethodAndBlock(&method_call, timeout_ms));
-  if (!response) {
-    std::cout << "Failed to receive a response." << std::endl;
-    return false;
-  }
-
-  dbus::MessageReader reader(response.get());
-  std::string device_id;
-  if (!reader.PopString(&device_id)) {
-    std::cout << "No device ID in response." << std::endl;
-    return false;
-  }
-
-  std::cout << "Device ID is "
-            << (device_id.empty() ? std::string("<unregistered>") : device_id)
-            << std::endl;
-  return true;
-}
-
-bool CallManagerUpdateState(dbus::ObjectProxy* proxy,
-                            const std::string& json_blob) {
-  dbus::MethodCall method_call(
-      buffet::dbus_constants::kManagerInterface,
-      buffet::dbus_constants::kManagerUpdateStateMethod);
-  dbus::MessageWriter writer(&method_call);
-  writer.AppendString(json_blob);
-  scoped_ptr<dbus::Response> response(
-    proxy->CallMethodAndBlock(&method_call, default_timeout_ms));
-  if (!response) {
-    std::cout << "Failed to receive a response." << std::endl;
-    return false;
-  }
-  return true;
-}
-
 void usage() {
   std::cerr << "Possible commands:" << std::endl;
   std::cerr << "  " << kManagerTestMethod << std::endl;
@@ -187,62 +36,97 @@
   std::cerr << "  " << kManagerUpdateStateMethod << std::endl;
 }
 
-} // namespace
-
-int main(int argc, char** argv) {
-  CommandLine::Init(argc, argv);
-  CommandLine* cl = CommandLine::ForCurrentProcess();
-
-  dbus::Bus::Options options;
-  options.bus_type = dbus::Bus::SYSTEM;
-  scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
-
-  CommandLine::StringVector args = cl->GetArgs();
-  if (args.empty()) {
-    usage();
-    return EX_USAGE;
+class BuffetHelperProxy {
+ public:
+  int Init() {
+    dbus::Bus::Options options;
+    options.bus_type = dbus::Bus::SYSTEM;
+    bus_ = new dbus::Bus(options);
+    manager_proxy_ = bus_->GetObjectProxy(
+        kServiceName,
+        dbus::ObjectPath(kManagerServicePath));
+    return EX_OK;
   }
 
-  // Pop the command off of the args list.
-  std::string command = args.front();
-  args.erase(args.begin());
-  bool success = false;
-  if (command.compare(kManagerTestMethod) == 0) {
-    auto proxy = GetBuffetDBusProxy(
-        bus, buffet::dbus_constants::kManagerServicePath);
-    success = CallTestMethod(proxy);
-  } else if (command.compare(kManagerCheckDeviceRegistered) == 0 ||
-             command.compare("cr") == 0) {
+  int CallTestMethod(const CommandLine::StringVector& args) {
+    dbus::MethodCall method_call(kManagerInterface, kManagerTestMethod);
+    scoped_ptr<dbus::Response> response(
+        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
+    if (!response) {
+      std::cout << "Failed to receive a response." << std::endl;
+      return EX_UNAVAILABLE;
+    }
+    std::cout << "Received a response." << std::endl;
+    return EX_OK;
+  }
+
+  int CallManagerCheckDeviceRegistered(const CommandLine::StringVector& args) {
     if (!args.empty()) {
       std::cerr << "Invalid number of arguments for "
-        << "Manager." << kManagerCheckDeviceRegistered << std::endl;
+                << "Manager." << kManagerCheckDeviceRegistered << std::endl;
       usage();
       return EX_USAGE;
     }
-    auto proxy = GetBuffetDBusProxy(
-      bus, buffet::dbus_constants::kManagerServicePath);
-    success = CallManagerCheckDeviceRegistered(proxy);
-  } else if (command.compare(kManagerGetDeviceInfo) == 0 ||
-             command.compare("di") == 0) {
+    dbus::MethodCall method_call(
+        kManagerInterface, kManagerCheckDeviceRegistered);
+
+    scoped_ptr<dbus::Response> response(
+        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
+    if (!response) {
+      std::cout << "Failed to receive a response." << std::endl;
+      return EX_UNAVAILABLE;
+    }
+
+    dbus::MessageReader reader(response.get());
+    std::string device_id;
+    if (!reader.PopString(&device_id)) {
+      std::cout << "No device ID in response." << std::endl;
+      return EX_SOFTWARE;
+    }
+
+    std::cout << "Device ID: "
+              << (device_id.empty() ? std::string("<unregistered>") : device_id)
+              << std::endl;
+    return EX_OK;
+  }
+
+  int CallManagerGetDeviceInfo(const CommandLine::StringVector& args) {
     if (!args.empty()) {
       std::cerr << "Invalid number of arguments for "
-        << "Manager." << kManagerGetDeviceInfo << std::endl;
+                << "Manager." << kManagerGetDeviceInfo << std::endl;
       usage();
       return EX_USAGE;
     }
-    auto proxy = GetBuffetDBusProxy(
-      bus, buffet::dbus_constants::kManagerServicePath);
-    success = CallManagerGetDeviceInfo(proxy);
-  } else if (command.compare(kManagerStartRegisterDevice) == 0 ||
-             command.compare("sr") == 0) {
+    dbus::MethodCall method_call(
+        kManagerInterface, kManagerGetDeviceInfo);
+
+    scoped_ptr<dbus::Response> response(
+        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
+    if (!response) {
+      std::cout << "Failed to receive a response." << std::endl;
+      return EX_UNAVAILABLE;
+    }
+
+    dbus::MessageReader reader(response.get());
+    std::string device_info;
+    if (!reader.PopString(&device_info)) {
+      std::cout << "No device info in response." << std::endl;
+      return EX_SOFTWARE;
+    }
+
+    std::cout << "Device Info: "
+      << (device_info.empty() ? std::string("<unregistered>") : device_info)
+      << std::endl;
+    return EX_OK;
+  }
+
+  int CallManagerStartRegisterDevice(const CommandLine::StringVector& args) {
     if (args.size() > 1) {
       std::cerr << "Invalid number of arguments for "
                 << "Manager." << kManagerStartRegisterDevice << std::endl;
       usage();
       return EX_USAGE;
     }
-    auto proxy = GetBuffetDBusProxy(
-        bus, buffet::dbus_constants::kManagerServicePath);
     std::map<std::string, std::shared_ptr<base::Value>> params;
 
     if (!args.empty()) {
@@ -254,42 +138,147 @@
       }
     }
 
-    success = CallManagerStartRegisterDevice(proxy, params);
-  } else if (command.compare(kManagerFinishRegisterDevice) == 0 ||
-             command.compare("fr") == 0) {
+    dbus::MethodCall method_call(
+        kManagerInterface, kManagerStartRegisterDevice);
+    dbus::MessageWriter writer(&method_call);
+    dbus::MessageWriter dict_writer(nullptr);
+    writer.OpenArray("{sv}", &dict_writer);
+    for (auto&& pair : params) {
+      dbus::MessageWriter dict_entry_writer(nullptr);
+      dict_writer.OpenDictEntry(&dict_entry_writer);
+      dict_entry_writer.AppendString(pair.first);
+      dbus::AppendBasicTypeValueDataAsVariant(&dict_entry_writer,
+                                              *pair.second.get());
+      dict_writer.CloseContainer(&dict_entry_writer);
+    }
+    writer.CloseContainer(&dict_writer);
+
+    static const int timeout_ms = 3000;
+    scoped_ptr<dbus::Response> response(
+        manager_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
+    if (!response) {
+      std::cout << "Failed to receive a response." << std::endl;
+      return EX_UNAVAILABLE;
+    }
+
+    dbus::MessageReader reader(response.get());
+    std::string info;
+    if (!reader.PopString(&info)) {
+      std::cout << "No valid response." << std::endl;
+      return EX_SOFTWARE;
+    }
+
+    std::cout << "Registration started: " << info << std::endl;
+    return EX_OK;
+  }
+
+  int CallManagerFinishRegisterDevice(const CommandLine::StringVector& args) {
     if (args.size() > 1) {
       std::cerr << "Invalid number of arguments for "
                 << "Manager." << kManagerFinishRegisterDevice << std::endl;
       usage();
       return EX_USAGE;
     }
-    auto proxy = GetBuffetDBusProxy(
-        bus, buffet::dbus_constants::kManagerServicePath);
-    success = CallManagerFinishRegisterDevice(
-        proxy, !args.empty() ? args.front() : std::string());
-  } else if (command.compare(kManagerUpdateStateMethod) == 0 ||
-             command.compare("us") == 0) {
+    dbus::MethodCall method_call(
+        kManagerInterface, kManagerFinishRegisterDevice);
+    dbus::MessageWriter writer(&method_call);
+    std::string user_auth_code;
+    if (!args.empty()) { user_auth_code = args.front(); }
+    writer.AppendString(user_auth_code);
+    static const int timeout_ms = 10000;
+    scoped_ptr<dbus::Response> response(
+        manager_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
+    if (!response) {
+      std::cout << "Failed to receive a response." << std::endl;
+      return EX_UNAVAILABLE;
+    }
+
+    dbus::MessageReader reader(response.get());
+    std::string device_id;
+    if (!reader.PopString(&device_id)) {
+      std::cout << "No device ID in response." << std::endl;
+      return EX_SOFTWARE;
+    }
+
+    std::cout << "Device ID is "
+              << (device_id.empty() ? std::string("<unregistered>") : device_id)
+              << std::endl;
+    return EX_OK;
+  }
+
+  int CallManagerUpdateState(const CommandLine::StringVector& args) {
     if (args.size() != 1) {
       std::cerr << "Invalid number of arguments for "
                 << "Manager." << kManagerUpdateStateMethod << std::endl;
       usage();
       return EX_USAGE;
     }
-    auto proxy = GetBuffetDBusProxy(
-        bus, buffet::dbus_constants::kManagerServicePath);
-    success = CallManagerUpdateState(proxy, args.front());
-  } else {
-    std::cerr << "Unknown command: " << command << std::endl;
+    dbus::MethodCall method_call(
+        kManagerInterface, kManagerUpdateStateMethod);
+    dbus::MessageWriter writer(&method_call);
+    writer.AppendString(args.front());
+    scoped_ptr<dbus::Response> response(
+        manager_proxy_->CallMethodAndBlock(&method_call, default_timeout_ms));
+    if (!response) {
+      std::cout << "Failed to receive a response." << std::endl;
+      return EX_UNAVAILABLE;
+    }
+    return EX_OK;
+  }
+
+ private:
+  scoped_refptr<dbus::Bus> bus_;
+  dbus::ObjectProxy* manager_proxy_{nullptr};
+};
+
+} // namespace
+
+int main(int argc, char** argv) {
+  CommandLine::Init(argc, argv);
+  CommandLine* cl = CommandLine::ForCurrentProcess();
+  CommandLine::StringVector args = cl->GetArgs();
+  if (args.empty()) {
     usage();
     return EX_USAGE;
   }
 
-  if (success) {
-    std::cout << "Done." << std::endl;
-    return EX_OK;
+  // Pop the command off of the args list.
+  std::string command = args.front();
+  args.erase(args.begin());
+  int err = EX_USAGE;
+  BuffetHelperProxy helper;
+  err = helper.Init();
+  if (err) {
+    std::cerr << "Error initializing proxies." << std::endl;
+    return err;
   }
 
-  std::cerr << "Done, with errors." << std::endl;
-  return 1;
-}
+  if (command.compare(kManagerTestMethod) == 0) {
+    err = helper.CallTestMethod(args);
+  } else if (command.compare(kManagerCheckDeviceRegistered) == 0 ||
+             command.compare("cr") == 0) {
+    err = helper.CallManagerCheckDeviceRegistered(args);
+  } else if (command.compare(kManagerGetDeviceInfo) == 0 ||
+             command.compare("di") == 0) {
+    err = helper.CallManagerGetDeviceInfo(args);
+  } else if (command.compare(kManagerStartRegisterDevice) == 0 ||
+             command.compare("sr") == 0) {
+    err = helper.CallManagerStartRegisterDevice(args);
+  } else if (command.compare(kManagerFinishRegisterDevice) == 0 ||
+             command.compare("fr") == 0) {
+    err = helper.CallManagerFinishRegisterDevice(args);
+  } else if (command.compare(kManagerUpdateStateMethod) == 0 ||
+             command.compare("us") == 0) {
+    err = helper.CallManagerUpdateState(args);
+  } else {
+    std::cerr << "Unknown command: " << command << std::endl;
+    usage();
+  }
 
+  if (err) {
+    std::cerr << "Done, with errors." << std::endl;
+  } else {
+    std::cout << "Done." << std::endl;
+  }
+  return err;
+}