// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos-dbus-bindings/proxy_generator.h"

#include <string>
#include <vector>

#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <gtest/gtest.h>

#include "chromeos-dbus-bindings/interface.h"
#include "chromeos-dbus-bindings/service_config.h"
#include "chromeos-dbus-bindings/test_utils.h"

using std::string;
using std::vector;
using testing::Test;

namespace chromeos_dbus_bindings {

namespace {

const char kDBusTypeArryOfObjects[] = "ao";
const char kDBusTypeArryOfStrings[] = "as";
const char kDBusTypeBool[] = "b";
const char kDBusTypeByte[] = "y";
const char kDBusTypeInt32[] = "i";
const char kDBusTypeInt64[] = "x";
const char kDBusTypeString[] = "s";

const char kExpectedContent[] = R"literal_string(
#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/dbus/dbus_property.h>
#include <brillo/dbus/dbus_signal_handler.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/errors/error.h>
#include <brillo/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::TestInterface.
class TestInterfaceProxyInterface {
 public:
  virtual ~TestInterfaceProxyInterface() = default;

  virtual bool Elements(
      const std::string& in_space_walk,
      const std::vector<dbus::ObjectPath>& in_ramblin_man,
      std::string* out_3,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void ElementsAsync(
      const std::string& in_space_walk,
      const std::vector<dbus::ObjectPath>& in_ramblin_man,
      base::OnceCallback<void(const std::string&)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual bool ReturnToPatagonia(
      int64_t* out_1,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void ReturnToPatagoniaAsync(
      base::OnceCallback<void(int64_t)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual bool NiceWeatherForDucks(
      bool in_1,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void NiceWeatherForDucksAsync(
      bool in_1,
      base::OnceCallback<void()> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  // Comment line1
  // line2
  virtual bool ExperimentNumberSix(
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  // Comment line1
  // line2
  virtual void ExperimentNumberSixAsync(
      base::OnceCallback<void()> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual bool NervousTension(
      const PageOne& in_page_one,
      Pushy* out_pushy,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void NervousTensionAsync(
      const PageOne& in_page_one,
      base::OnceCallback<void(const Pushy& /*pushy*/)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) = 0;

  virtual void RegisterTheCurseOfKaZarSignalHandler(
      const base::RepeatingCallback<void(const std::vector<std::string>&,
                                         uint8_t)>& signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::TestInterface.
class TestInterfaceProxy final : public TestInterfaceProxyInterface {
 public:
  TestInterfaceProxy(
      const scoped_refptr<dbus::Bus>& bus,
      const std::string& service_name) :
          bus_{bus},
          service_name_{service_name},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  TestInterfaceProxy(const TestInterfaceProxy&) = delete;
  TestInterfaceProxy& operator=(const TestInterfaceProxy&) = delete;

  ~TestInterfaceProxy() override {
  }

  void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) override {
    brillo::dbus_utils::ConnectToSignal(
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "Closer",
        signal_callback,
        std::move(on_connected_callback));
  }

  void RegisterTheCurseOfKaZarSignalHandler(
      const base::RepeatingCallback<void(const std::vector<std::string>&,
                                         uint8_t)>& signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) override {
    brillo::dbus_utils::ConnectToSignal(
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "TheCurseOfKaZar",
        signal_callback,
        std::move(on_connected_callback));
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

  bool Elements(
      const std::string& in_space_walk,
      const std::vector<dbus::ObjectPath>& in_ramblin_man,
      std::string* out_3,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "Elements",
        error,
        in_space_walk,
        in_ramblin_man);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error, out_3);
  }

  void ElementsAsync(
      const std::string& in_space_walk,
      const std::vector<dbus::ObjectPath>& in_ramblin_man,
      base::OnceCallback<void(const std::string&)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "Elements",
        std::move(success_callback),
        std::move(error_callback),
        in_space_walk,
        in_ramblin_man);
  }

  bool ReturnToPatagonia(
      int64_t* out_1,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "ReturnToPatagonia",
        error);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error, out_1);
  }

  void ReturnToPatagoniaAsync(
      base::OnceCallback<void(int64_t)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "ReturnToPatagonia",
        std::move(success_callback),
        std::move(error_callback));
  }

  bool NiceWeatherForDucks(
      bool in_1,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "NiceWeatherForDucks",
        error,
        in_1);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error);
  }

  void NiceWeatherForDucksAsync(
      bool in_1,
      base::OnceCallback<void()> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "NiceWeatherForDucks",
        std::move(success_callback),
        std::move(error_callback),
        in_1);
  }

  // Comment line1
  // line2
  bool ExperimentNumberSix(
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "ExperimentNumberSix",
        error);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error);
  }

  // Comment line1
  // line2
  void ExperimentNumberSixAsync(
      base::OnceCallback<void()> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "ExperimentNumberSix",
        std::move(success_callback),
        std::move(error_callback));
  }

  bool NervousTension(
      const PageOne& in_page_one,
      Pushy* out_pushy,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "NervousTension",
        error,
        in_page_one);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error, out_pushy);
  }

  void NervousTensionAsync(
      const PageOne& in_page_one,
      base::OnceCallback<void(const Pushy& /*pushy*/)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "NervousTension",
        std::move(success_callback),
        std::move(error_callback),
        in_page_one);
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  std::string service_name_;
  const dbus::ObjectPath object_path_{"/org/chromium/Test"};
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::TestInterface2.
class TestInterface2ProxyInterface {
 public:
  virtual ~TestInterface2ProxyInterface() = default;

  virtual bool GetPersonInfo(
      std::string* out_name,
      int32_t* out_age,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void GetPersonInfoAsync(
      base::OnceCallback<void(const std::string& /*name*/, int32_t /*age*/)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::TestInterface2.
class TestInterface2Proxy final : public TestInterface2ProxyInterface {
 public:
  TestInterface2Proxy(
      const scoped_refptr<dbus::Bus>& bus,
      const std::string& service_name,
      const dbus::ObjectPath& object_path) :
          bus_{bus},
          service_name_{service_name},
          object_path_{object_path},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  TestInterface2Proxy(const TestInterface2Proxy&) = delete;
  TestInterface2Proxy& operator=(const TestInterface2Proxy&) = delete;

  ~TestInterface2Proxy() override {
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

  bool GetPersonInfo(
      std::string* out_name,
      int32_t* out_age,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface2",
        "GetPersonInfo",
        error);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error, out_name, out_age);
  }

  void GetPersonInfoAsync(
      base::OnceCallback<void(const std::string& /*name*/, int32_t /*age*/)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface2",
        "GetPersonInfo",
        std::move(success_callback),
        std::move(error_callback));
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  std::string service_name_;
  dbus::ObjectPath object_path_;
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org
)literal_string";

const char kExpectedContentWithService[] = R"literal_string(
#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/dbus/dbus_property.h>
#include <brillo/dbus/dbus_signal_handler.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/errors/error.h>
#include <brillo/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::TestInterface.
class TestInterfaceProxyInterface {
 public:
  virtual ~TestInterfaceProxyInterface() = default;

  virtual void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::TestInterface.
class TestInterfaceProxy final : public TestInterfaceProxyInterface {
 public:
  TestInterfaceProxy(const scoped_refptr<dbus::Bus>& bus) :
      bus_{bus},
      dbus_object_proxy_{
          bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  TestInterfaceProxy(const TestInterfaceProxy&) = delete;
  TestInterfaceProxy& operator=(const TestInterfaceProxy&) = delete;

  ~TestInterfaceProxy() override {
  }

  void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) override {
    brillo::dbus_utils::ConnectToSignal(
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "Closer",
        signal_callback,
        std::move(on_connected_callback));
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  const std::string service_name_{"org.chromium.Test"};
  const dbus::ObjectPath object_path_{"/org/chromium/Test"};
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::TestInterface2.
class TestInterface2ProxyInterface {
 public:
  virtual ~TestInterface2ProxyInterface() = default;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::TestInterface2.
class TestInterface2Proxy final : public TestInterface2ProxyInterface {
 public:
  TestInterface2Proxy(
      const scoped_refptr<dbus::Bus>& bus,
      const dbus::ObjectPath& object_path) :
          bus_{bus},
          object_path_{object_path},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  TestInterface2Proxy(const TestInterface2Proxy&) = delete;
  TestInterface2Proxy& operator=(const TestInterface2Proxy&) = delete;

  ~TestInterface2Proxy() override {
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  const std::string service_name_{"org.chromium.Test"};
  dbus::ObjectPath object_path_;
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org
)literal_string";

const char kExpectedContentWithObjectManager[] = R"literal_string(
#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/dbus/dbus_property.h>
#include <brillo/dbus/dbus_signal_handler.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/errors/error.h>
#include <brillo/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>

namespace org {
namespace chromium {
class ObjectManagerProxy;
}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::Itf1.
class Itf1ProxyInterface {
 public:
  virtual ~Itf1ProxyInterface() = default;

  virtual void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) = 0;

  static const char* DataName() { return "Data"; }
  virtual const std::string& data() const = 0;
  static const char* NameName() { return "Name"; }
  virtual const std::string& name() const = 0;
  virtual void set_name(const std::string& value,
                        base::OnceCallback<void(bool)> callback) = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;

  virtual void SetPropertyChangedCallback(
      const base::RepeatingCallback<void(Itf1ProxyInterface*, const std::string&)>& callback) = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::Itf1.
class Itf1Proxy final : public Itf1ProxyInterface {
 public:
  class PropertySet : public dbus::PropertySet {
   public:
    PropertySet(dbus::ObjectProxy* object_proxy,
                const PropertyChangedCallback& callback)
        : dbus::PropertySet{object_proxy,
                            "org.chromium.Itf1",
                            callback} {
      RegisterProperty(DataName(), &data);
      RegisterProperty(NameName(), &name);
    }
    PropertySet(const PropertySet&) = delete;
    PropertySet& operator=(const PropertySet&) = delete;

    brillo::dbus_utils::Property<std::string> data;
    brillo::dbus_utils::Property<std::string> name;

  };

  Itf1Proxy(
      const scoped_refptr<dbus::Bus>& bus,
      const std::string& service_name,
      PropertySet* property_set) :
          bus_{bus},
          service_name_{service_name},
          property_set_{property_set},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  Itf1Proxy(const Itf1Proxy&) = delete;
  Itf1Proxy& operator=(const Itf1Proxy&) = delete;

  ~Itf1Proxy() override {
  }

  void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) override {
    brillo::dbus_utils::ConnectToSignal(
        dbus_object_proxy_,
        "org.chromium.Itf1",
        "Closer",
        signal_callback,
        std::move(on_connected_callback));
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

  void SetPropertyChangedCallback(
      const base::RepeatingCallback<void(Itf1ProxyInterface*, const std::string&)>& callback) override {
    on_property_changed_ = callback;
  }

  const PropertySet* GetProperties() const { return &(*property_set_); }
  PropertySet* GetProperties() { return &(*property_set_); }

  const std::string& data() const override {
    return property_set_->data.value();
  }

  const std::string& name() const override {
    return property_set_->name.value();
  }

  void set_name(const std::string& value,
                base::OnceCallback<void(bool)> callback) override {
    property_set_->name.Set(value, std::move(callback));
  }

 private:
  void OnPropertyChanged(const std::string& property_name) {
    if (!on_property_changed_.is_null())
      on_property_changed_.Run(this, property_name);
  }

  scoped_refptr<dbus::Bus> bus_;
  std::string service_name_;
  const dbus::ObjectPath object_path_{"/org/chromium/Test/Object"};
  PropertySet* property_set_;
  base::RepeatingCallback<void(Itf1ProxyInterface*, const std::string&)> on_property_changed_;
  dbus::ObjectProxy* dbus_object_proxy_;

  friend class org::chromium::ObjectManagerProxy;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::Itf2.
class Itf2ProxyInterface {
 public:
  virtual ~Itf2ProxyInterface() = default;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::Itf2.
class Itf2Proxy final : public Itf2ProxyInterface {
 public:
  class PropertySet : public dbus::PropertySet {
   public:
    PropertySet(dbus::ObjectProxy* object_proxy,
                const PropertyChangedCallback& callback)
        : dbus::PropertySet{object_proxy,
                            "org.chromium.Itf2",
                            callback} {
    }
    PropertySet(const PropertySet&) = delete;
    PropertySet& operator=(const PropertySet&) = delete;


  };

  Itf2Proxy(
      const scoped_refptr<dbus::Bus>& bus,
      const std::string& service_name,
      const dbus::ObjectPath& object_path) :
          bus_{bus},
          service_name_{service_name},
          object_path_{object_path},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  Itf2Proxy(const Itf2Proxy&) = delete;
  Itf2Proxy& operator=(const Itf2Proxy&) = delete;

  ~Itf2Proxy() override {
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  std::string service_name_;
  dbus::ObjectPath object_path_;
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

class ObjectManagerProxy : public dbus::ObjectManager::Interface {
 public:
  ObjectManagerProxy(const scoped_refptr<dbus::Bus>& bus,
                     const std::string& service_name)
      : bus_{bus},
        service_name_{service_name},
        dbus_object_manager_{bus->GetObjectManager(
            service_name,
            dbus::ObjectPath{"/org/chromium/Test"})} {
    dbus_object_manager_->RegisterInterface("org.chromium.Itf1", this);
    dbus_object_manager_->RegisterInterface("org.chromium.Itf2", this);
  }

  ObjectManagerProxy(const ObjectManagerProxy&) = delete;
  ObjectManagerProxy& operator=(const ObjectManagerProxy&) = delete;

  ~ObjectManagerProxy() override {
    dbus_object_manager_->UnregisterInterface("org.chromium.Itf1");
    dbus_object_manager_->UnregisterInterface("org.chromium.Itf2");
  }

  dbus::ObjectManager* GetObjectManagerProxy() const {
    return dbus_object_manager_;
  }

  org::chromium::Itf1ProxyInterface* GetItf1Proxy() {
    if (itf1_instances_.empty())
      return nullptr;
    return itf1_instances_.begin()->second.get();
  }
  std::vector<org::chromium::Itf1ProxyInterface*> GetItf1Instances() const {
    std::vector<org::chromium::Itf1ProxyInterface*> values;
    values.reserve(itf1_instances_.size());
    for (const auto& pair : itf1_instances_)
      values.push_back(pair.second.get());
    return values;
  }
  void SetItf1AddedCallback(
      const base::RepeatingCallback<void(org::chromium::Itf1ProxyInterface*)>& callback) {
    on_itf1_added_ = callback;
  }
  void SetItf1RemovedCallback(
      const base::RepeatingCallback<void(const dbus::ObjectPath&)>& callback) {
    on_itf1_removed_ = callback;
  }

  org::chromium::Itf2ProxyInterface* GetItf2Proxy(
      const dbus::ObjectPath& object_path) {
    auto p = itf2_instances_.find(object_path);
    if (p != itf2_instances_.end())
      return p->second.get();
    return nullptr;
  }
  std::vector<org::chromium::Itf2ProxyInterface*> GetItf2Instances() const {
    std::vector<org::chromium::Itf2ProxyInterface*> values;
    values.reserve(itf2_instances_.size());
    for (const auto& pair : itf2_instances_)
      values.push_back(pair.second.get());
    return values;
  }
  void SetItf2AddedCallback(
      const base::RepeatingCallback<void(org::chromium::Itf2ProxyInterface*)>& callback) {
    on_itf2_added_ = callback;
  }
  void SetItf2RemovedCallback(
      const base::RepeatingCallback<void(const dbus::ObjectPath&)>& callback) {
    on_itf2_removed_ = callback;
  }

 private:
  void OnPropertyChanged(const dbus::ObjectPath& object_path,
                         const std::string& interface_name,
                         const std::string& property_name) {
    if (interface_name == "org.chromium.Itf1") {
      auto p = itf1_instances_.find(object_path);
      if (p == itf1_instances_.end())
        return;
      p->second->OnPropertyChanged(property_name);
      return;
    }
  }

  void ObjectAdded(
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.Itf1") {
      auto property_set =
          static_cast<org::chromium::Itf1Proxy::PropertySet*>(
              dbus_object_manager_->GetProperties(object_path, interface_name));
      std::unique_ptr<org::chromium::Itf1Proxy> itf1_proxy{
        new org::chromium::Itf1Proxy{bus_, service_name_, property_set}
      };
      auto p = itf1_instances_.emplace(object_path, std::move(itf1_proxy));
      if (!on_itf1_added_.is_null())
        on_itf1_added_.Run(p.first->second.get());
      return;
    }
    if (interface_name == "org.chromium.Itf2") {
      std::unique_ptr<org::chromium::Itf2Proxy> itf2_proxy{
        new org::chromium::Itf2Proxy{bus_, service_name_, object_path}
      };
      auto p = itf2_instances_.emplace(object_path, std::move(itf2_proxy));
      if (!on_itf2_added_.is_null())
        on_itf2_added_.Run(p.first->second.get());
      return;
    }
  }

  void ObjectRemoved(
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.Itf1") {
      auto p = itf1_instances_.find(object_path);
      if (p != itf1_instances_.end()) {
        if (!on_itf1_removed_.is_null())
          on_itf1_removed_.Run(object_path);
        itf1_instances_.erase(p);
      }
      return;
    }
    if (interface_name == "org.chromium.Itf2") {
      auto p = itf2_instances_.find(object_path);
      if (p != itf2_instances_.end()) {
        if (!on_itf2_removed_.is_null())
          on_itf2_removed_.Run(object_path);
        itf2_instances_.erase(p);
      }
      return;
    }
  }

  dbus::PropertySet* CreateProperties(
      dbus::ObjectProxy* object_proxy,
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.Itf1") {
      return new org::chromium::Itf1Proxy::PropertySet{
          object_proxy,
          base::BindRepeating(&ObjectManagerProxy::OnPropertyChanged,
                              weak_ptr_factory_.GetWeakPtr(),
                              object_path,
                              interface_name)
      };
    }
    if (interface_name == "org.chromium.Itf2") {
      return new org::chromium::Itf2Proxy::PropertySet{
          object_proxy,
          base::BindRepeating(&ObjectManagerProxy::OnPropertyChanged,
                              weak_ptr_factory_.GetWeakPtr(),
                              object_path,
                              interface_name)
      };
    }
    LOG(FATAL) << "Creating properties for unsupported interface "
               << interface_name;
    return nullptr;
  }

  scoped_refptr<dbus::Bus> bus_;
  std::string service_name_;
  dbus::ObjectManager* dbus_object_manager_;
  std::map<dbus::ObjectPath,
           std::unique_ptr<org::chromium::Itf1Proxy>> itf1_instances_;
  base::RepeatingCallback<void(org::chromium::Itf1ProxyInterface*)> on_itf1_added_;
  base::RepeatingCallback<void(const dbus::ObjectPath&)> on_itf1_removed_;
  std::map<dbus::ObjectPath,
           std::unique_ptr<org::chromium::Itf2Proxy>> itf2_instances_;
  base::RepeatingCallback<void(org::chromium::Itf2ProxyInterface*)> on_itf2_added_;
  base::RepeatingCallback<void(const dbus::ObjectPath&)> on_itf2_removed_;
  base::WeakPtrFactory<ObjectManagerProxy> weak_ptr_factory_{this};
};

}  // namespace chromium
}  // namespace org
)literal_string";

const char kExpectedContentWithProperties[] = R"literal_string(
#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/dbus/dbus_property.h>
#include <brillo/dbus/dbus_signal_handler.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/errors/error.h>
#include <brillo/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::Test.
class TestProxyInterface {
 public:
  virtual ~TestProxyInterface() = default;

  static const char* DataName() { return "Data"; }
  virtual const std::string& data() const = 0;
  static const char* NameName() { return "Name"; }
  virtual const std::string& name() const = 0;
  virtual void set_name(const std::string& value,
                        base::OnceCallback<void(bool)> callback) = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;

  virtual void InitializeProperties(
      const base::RepeatingCallback<void(TestProxyInterface*, const std::string&)>& callback) = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::Test.
class TestProxy final : public TestProxyInterface {
 public:
  class PropertySet : public dbus::PropertySet {
   public:
    PropertySet(dbus::ObjectProxy* object_proxy,
                const PropertyChangedCallback& callback)
        : dbus::PropertySet{object_proxy,
                            "org.chromium.Test",
                            callback} {
      RegisterProperty(DataName(), &data);
      RegisterProperty(NameName(), &name);
    }
    PropertySet(const PropertySet&) = delete;
    PropertySet& operator=(const PropertySet&) = delete;

    brillo::dbus_utils::Property<std::string> data;
    brillo::dbus_utils::Property<std::string> name;

  };

  TestProxy(const scoped_refptr<dbus::Bus>& bus) :
      bus_{bus},
      dbus_object_proxy_{
          bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  TestProxy(const TestProxy&) = delete;
  TestProxy& operator=(const TestProxy&) = delete;

  ~TestProxy() override {
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

  void InitializeProperties(
      const base::RepeatingCallback<void(TestProxyInterface*, const std::string&)>& callback) override {
    property_set_.reset(
        new PropertySet(dbus_object_proxy_, base::BindRepeating(callback, this)));
    property_set_->ConnectSignals();
    property_set_->GetAll();
  }

  const PropertySet* GetProperties() const { return &(*property_set_); }
  PropertySet* GetProperties() { return &(*property_set_); }

  const std::string& data() const override {
    return property_set_->data.value();
  }

  const std::string& name() const override {
    return property_set_->name.value();
  }

  void set_name(const std::string& value,
                base::OnceCallback<void(bool)> callback) override {
    property_set_->name.Set(value, std::move(callback));
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  const std::string service_name_{"org.chromium.Test"};
  const dbus::ObjectPath object_path_{"/org/chromium/Test"};
  dbus::ObjectProxy* dbus_object_proxy_;
  std::unique_ptr<PropertySet> property_set_;

};

}  // namespace chromium
}  // namespace org
)literal_string";

const char kExpectedContentWithObjectManagerAndServiceName[] = R"literal_string(
#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/dbus/dbus_property.h>
#include <brillo/dbus/dbus_signal_handler.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/errors/error.h>
#include <brillo/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>

namespace org {
namespace chromium {
class ObjectManagerProxy;
}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::Itf1.
class Itf1ProxyInterface {
 public:
  virtual ~Itf1ProxyInterface() = default;

  virtual void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::Itf1.
class Itf1Proxy final : public Itf1ProxyInterface {
 public:
  class PropertySet : public dbus::PropertySet {
   public:
    PropertySet(dbus::ObjectProxy* object_proxy,
                const PropertyChangedCallback& callback)
        : dbus::PropertySet{object_proxy,
                            "org.chromium.Itf1",
                            callback} {
    }
    PropertySet(const PropertySet&) = delete;
    PropertySet& operator=(const PropertySet&) = delete;


  };

  Itf1Proxy(const scoped_refptr<dbus::Bus>& bus) :
      bus_{bus},
      dbus_object_proxy_{
          bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  Itf1Proxy(const Itf1Proxy&) = delete;
  Itf1Proxy& operator=(const Itf1Proxy&) = delete;

  ~Itf1Proxy() override {
  }

  void RegisterCloserSignalHandler(
      base::RepeatingClosure signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) override {
    brillo::dbus_utils::ConnectToSignal(
        dbus_object_proxy_,
        "org.chromium.Itf1",
        "Closer",
        signal_callback,
        std::move(on_connected_callback));
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  const std::string service_name_{"org.chromium.Test"};
  const dbus::ObjectPath object_path_{"/org/chromium/Test/Object"};
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::Itf2.
class Itf2ProxyInterface {
 public:
  virtual ~Itf2ProxyInterface() = default;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::Itf2.
class Itf2Proxy final : public Itf2ProxyInterface {
 public:
  class PropertySet : public dbus::PropertySet {
   public:
    PropertySet(dbus::ObjectProxy* object_proxy,
                const PropertyChangedCallback& callback)
        : dbus::PropertySet{object_proxy,
                            "org.chromium.Itf2",
                            callback} {
    }
    PropertySet(const PropertySet&) = delete;
    PropertySet& operator=(const PropertySet&) = delete;


  };

  Itf2Proxy(
      const scoped_refptr<dbus::Bus>& bus,
      const dbus::ObjectPath& object_path) :
          bus_{bus},
          object_path_{object_path},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  Itf2Proxy(const Itf2Proxy&) = delete;
  Itf2Proxy& operator=(const Itf2Proxy&) = delete;

  ~Itf2Proxy() override {
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  const std::string service_name_{"org.chromium.Test"};
  dbus::ObjectPath object_path_;
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

class ObjectManagerProxy : public dbus::ObjectManager::Interface {
 public:
  ObjectManagerProxy(const scoped_refptr<dbus::Bus>& bus)
      : bus_{bus},
        dbus_object_manager_{bus->GetObjectManager(
            "org.chromium.Test",
            dbus::ObjectPath{"/org/chromium/Test"})} {
    dbus_object_manager_->RegisterInterface("org.chromium.Itf1", this);
    dbus_object_manager_->RegisterInterface("org.chromium.Itf2", this);
  }

  ObjectManagerProxy(const ObjectManagerProxy&) = delete;
  ObjectManagerProxy& operator=(const ObjectManagerProxy&) = delete;

  ~ObjectManagerProxy() override {
    dbus_object_manager_->UnregisterInterface("org.chromium.Itf1");
    dbus_object_manager_->UnregisterInterface("org.chromium.Itf2");
  }

  dbus::ObjectManager* GetObjectManagerProxy() const {
    return dbus_object_manager_;
  }

  org::chromium::Itf1ProxyInterface* GetItf1Proxy() {
    if (itf1_instances_.empty())
      return nullptr;
    return itf1_instances_.begin()->second.get();
  }
  std::vector<org::chromium::Itf1ProxyInterface*> GetItf1Instances() const {
    std::vector<org::chromium::Itf1ProxyInterface*> values;
    values.reserve(itf1_instances_.size());
    for (const auto& pair : itf1_instances_)
      values.push_back(pair.second.get());
    return values;
  }
  void SetItf1AddedCallback(
      const base::RepeatingCallback<void(org::chromium::Itf1ProxyInterface*)>& callback) {
    on_itf1_added_ = callback;
  }
  void SetItf1RemovedCallback(
      const base::RepeatingCallback<void(const dbus::ObjectPath&)>& callback) {
    on_itf1_removed_ = callback;
  }

  org::chromium::Itf2ProxyInterface* GetItf2Proxy(
      const dbus::ObjectPath& object_path) {
    auto p = itf2_instances_.find(object_path);
    if (p != itf2_instances_.end())
      return p->second.get();
    return nullptr;
  }
  std::vector<org::chromium::Itf2ProxyInterface*> GetItf2Instances() const {
    std::vector<org::chromium::Itf2ProxyInterface*> values;
    values.reserve(itf2_instances_.size());
    for (const auto& pair : itf2_instances_)
      values.push_back(pair.second.get());
    return values;
  }
  void SetItf2AddedCallback(
      const base::RepeatingCallback<void(org::chromium::Itf2ProxyInterface*)>& callback) {
    on_itf2_added_ = callback;
  }
  void SetItf2RemovedCallback(
      const base::RepeatingCallback<void(const dbus::ObjectPath&)>& callback) {
    on_itf2_removed_ = callback;
  }

 private:
  void OnPropertyChanged(const dbus::ObjectPath& /* object_path */,
                         const std::string& /* interface_name */,
                         const std::string& /* property_name */) {}

  void ObjectAdded(
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.Itf1") {
      std::unique_ptr<org::chromium::Itf1Proxy> itf1_proxy{
        new org::chromium::Itf1Proxy{bus_}
      };
      auto p = itf1_instances_.emplace(object_path, std::move(itf1_proxy));
      if (!on_itf1_added_.is_null())
        on_itf1_added_.Run(p.first->second.get());
      return;
    }
    if (interface_name == "org.chromium.Itf2") {
      std::unique_ptr<org::chromium::Itf2Proxy> itf2_proxy{
        new org::chromium::Itf2Proxy{bus_, object_path}
      };
      auto p = itf2_instances_.emplace(object_path, std::move(itf2_proxy));
      if (!on_itf2_added_.is_null())
        on_itf2_added_.Run(p.first->second.get());
      return;
    }
  }

  void ObjectRemoved(
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.Itf1") {
      auto p = itf1_instances_.find(object_path);
      if (p != itf1_instances_.end()) {
        if (!on_itf1_removed_.is_null())
          on_itf1_removed_.Run(object_path);
        itf1_instances_.erase(p);
      }
      return;
    }
    if (interface_name == "org.chromium.Itf2") {
      auto p = itf2_instances_.find(object_path);
      if (p != itf2_instances_.end()) {
        if (!on_itf2_removed_.is_null())
          on_itf2_removed_.Run(object_path);
        itf2_instances_.erase(p);
      }
      return;
    }
  }

  dbus::PropertySet* CreateProperties(
      dbus::ObjectProxy* object_proxy,
      const dbus::ObjectPath& object_path,
      const std::string& interface_name) override {
    if (interface_name == "org.chromium.Itf1") {
      return new org::chromium::Itf1Proxy::PropertySet{
          object_proxy,
          base::BindRepeating(&ObjectManagerProxy::OnPropertyChanged,
                              weak_ptr_factory_.GetWeakPtr(),
                              object_path,
                              interface_name)
      };
    }
    if (interface_name == "org.chromium.Itf2") {
      return new org::chromium::Itf2Proxy::PropertySet{
          object_proxy,
          base::BindRepeating(&ObjectManagerProxy::OnPropertyChanged,
                              weak_ptr_factory_.GetWeakPtr(),
                              object_path,
                              interface_name)
      };
    }
    LOG(FATAL) << "Creating properties for unsupported interface "
               << interface_name;
    return nullptr;
  }

  scoped_refptr<dbus::Bus> bus_;
  dbus::ObjectManager* dbus_object_manager_;
  std::map<dbus::ObjectPath,
           std::unique_ptr<org::chromium::Itf1Proxy>> itf1_instances_;
  base::RepeatingCallback<void(org::chromium::Itf1ProxyInterface*)> on_itf1_added_;
  base::RepeatingCallback<void(const dbus::ObjectPath&)> on_itf1_removed_;
  std::map<dbus::ObjectPath,
           std::unique_ptr<org::chromium::Itf2Proxy>> itf2_instances_;
  base::RepeatingCallback<void(org::chromium::Itf2ProxyInterface*)> on_itf2_added_;
  base::RepeatingCallback<void(const dbus::ObjectPath&)> on_itf2_removed_;
  base::WeakPtrFactory<ObjectManagerProxy> weak_ptr_factory_{this};
};

}  // namespace chromium
}  // namespace org
)literal_string";

const char kExpectedContentNewFileDescriptors[] = R"literal_string(
#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ref_counted.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_method_invoker.h>
#include <brillo/dbus/dbus_property.h>
#include <brillo/dbus/dbus_signal_handler.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/errors/error.h>
#include <brillo/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>

namespace org {
namespace chromium {

// Abstract interface proxy for org::chromium::TestInterface.
class TestInterfaceProxyInterface {
 public:
  virtual ~TestInterfaceProxyInterface() = default;

  virtual bool WrapFileDescriptor(
      const brillo::dbus_utils::FileDescriptor& in_1,
      base::ScopedFD* out_2,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void WrapFileDescriptorAsync(
      const brillo::dbus_utils::FileDescriptor& in_1,
      base::OnceCallback<void(const base::ScopedFD&)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) = 0;

  virtual void RegisterFileSignalHandler(
      const base::RepeatingCallback<void(const base::ScopedFD&)>& signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) = 0;

  virtual const dbus::ObjectPath& GetObjectPath() const = 0;
  virtual dbus::ObjectProxy* GetObjectProxy() const = 0;
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface proxy for org::chromium::TestInterface.
class TestInterfaceProxy final : public TestInterfaceProxyInterface {
 public:
  TestInterfaceProxy(
      const scoped_refptr<dbus::Bus>& bus,
      const std::string& service_name) :
          bus_{bus},
          service_name_{service_name},
          dbus_object_proxy_{
              bus_->GetObjectProxy(service_name_, object_path_)} {
  }

  TestInterfaceProxy(const TestInterfaceProxy&) = delete;
  TestInterfaceProxy& operator=(const TestInterfaceProxy&) = delete;

  ~TestInterfaceProxy() override {
  }

  void RegisterFileSignalHandler(
      const base::RepeatingCallback<void(const base::ScopedFD&)>& signal_callback,
      dbus::ObjectProxy::OnConnectedCallback on_connected_callback) override {
    brillo::dbus_utils::ConnectToSignal(
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "File",
        signal_callback,
        std::move(on_connected_callback));
  }

  void ReleaseObjectProxy(base::OnceClosure callback) {
    bus_->RemoveObjectProxy(service_name_, object_path_, std::move(callback));
  }

  const dbus::ObjectPath& GetObjectPath() const override {
    return object_path_;
  }

  dbus::ObjectProxy* GetObjectProxy() const override {
    return dbus_object_proxy_;
  }

  bool WrapFileDescriptor(
      const brillo::dbus_utils::FileDescriptor& in_1,
      base::ScopedFD* out_2,
      brillo::ErrorPtr* error,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    auto response = brillo::dbus_utils::CallMethodAndBlockWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "WrapFileDescriptor",
        error,
        in_1);
    return response && brillo::dbus_utils::ExtractMethodCallResults(
        response.get(), error, out_2);
  }

  void WrapFileDescriptorAsync(
      const brillo::dbus_utils::FileDescriptor& in_1,
      base::OnceCallback<void(const base::ScopedFD&)> success_callback,
      base::OnceCallback<void(brillo::Error*)> error_callback,
      int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT) override {
    brillo::dbus_utils::CallMethodWithTimeout(
        timeout_ms,
        dbus_object_proxy_,
        "org.chromium.TestInterface",
        "WrapFileDescriptor",
        std::move(success_callback),
        std::move(error_callback),
        in_1);
  }

 private:
  scoped_refptr<dbus::Bus> bus_;
  std::string service_name_;
  const dbus::ObjectPath object_path_{"/org/chromium/Test"};
  dbus::ObjectProxy* dbus_object_proxy_;

};

}  // namespace chromium
}  // namespace org

)literal_string";
}  // namespace

class ProxyGeneratorTest : public Test {
 public:
  void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }

 protected:
  base::FilePath CreateInputFile(const string& contents) {
    base::FilePath path;
    EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &path));
    int written = base::WriteFile(path, contents.c_str(), contents.size());
    EXPECT_EQ(contents.size(), static_cast<size_t>(written));
    return path;
  }

  base::ScopedTempDir temp_dir_;
};

TEST_F(ProxyGeneratorTest, GenerateAdaptors) {
  Interface interface;
  interface.name = "org.chromium.TestInterface";
  interface.path = "/org/chromium/Test";
  interface.methods.emplace_back(
      "Elements",
      vector<Interface::Argument>{{"space_walk", kDBusTypeString},
                                  {"ramblin_man", kDBusTypeArryOfObjects}},
      vector<Interface::Argument>{{"", kDBusTypeString}});
  interface.methods.emplace_back(
      "ReturnToPatagonia", vector<Interface::Argument>{},
      vector<Interface::Argument>{{"", kDBusTypeInt64}});
  interface.methods.emplace_back(
      "NiceWeatherForDucks", vector<Interface::Argument>{{"", kDBusTypeBool}},
      vector<Interface::Argument>{});
  interface.methods.emplace_back("ExperimentNumberSix");
  interface.methods.back().doc_string = "Comment line1\nline2";
  interface.methods.emplace_back(
      "NervousTension",
      vector<Interface::Argument>{
          {"page_one", string(kProtobufType) + "PageOne"}},
      vector<Interface::Argument>{{"pushy", string(kProtobufType) + "Pushy"}});

  interface.signals.emplace_back("Closer");
  interface.signals.emplace_back(
      "TheCurseOfKaZar",
      vector<Interface::Argument>{{"", kDBusTypeArryOfStrings},
                                  {"", kDBusTypeByte}});
  Interface interface2;
  interface2.name = "org.chromium.TestInterface2";
  interface2.methods.emplace_back(
      "GetPersonInfo", vector<Interface::Argument>{},
      vector<Interface::Argument>{{"name", kDBusTypeString},
                                  {"age", kDBusTypeInt32}});
  vector<Interface> interfaces{interface, interface2};
  base::FilePath output_path = temp_dir_.GetPath().Append("output.h");
  ServiceConfig config;
  ProxyGenerator gen;
  EXPECT_TRUE(gen.GenerateProxies(config, interfaces, output_path));
  string contents;
  EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
  // The header guards contain the (temporary) filename, so we search for
  // the content we need within the string.
  test_utils::EXPECT_TEXT_CONTAINED(kExpectedContent, contents);
}

TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithServiceName) {
  Interface interface;
  interface.name = "org.chromium.TestInterface";
  interface.path = "/org/chromium/Test";
  interface.signals.emplace_back("Closer");
  Interface interface2;
  interface2.name = "org.chromium.TestInterface2";
  vector<Interface> interfaces{interface, interface2};
  base::FilePath output_path = temp_dir_.GetPath().Append("output2.h");
  ServiceConfig config;
  config.service_name = "org.chromium.Test";
  ProxyGenerator gen;
  EXPECT_TRUE(gen.GenerateProxies(config, interfaces, output_path));
  string contents;
  EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
  // The header guards contain the (temporary) filename, so we search for
  // the content we need within the string.
  test_utils::EXPECT_TEXT_CONTAINED(kExpectedContentWithService, contents);
}

TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithProperties) {
  Interface interface;
  interface.name = "org.chromium.Test";
  interface.path = "/org/chromium/Test";
  interface.properties.emplace_back("Data", "s", "read");
  interface.properties.emplace_back("Name", "s", "readwrite");
  vector<Interface> interfaces{interface};
  base::FilePath output_path = temp_dir_.GetPath().Append("output2.h");
  ServiceConfig config;
  config.service_name = "org.chromium.Test";
  ProxyGenerator gen;
  EXPECT_TRUE(gen.GenerateProxies(config, interfaces, output_path));
  string contents;
  EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
  // The header guards contain the (temporary) filename, so we search for
  // the content we need within the string.
  test_utils::EXPECT_TEXT_CONTAINED(kExpectedContentWithProperties, contents);
}

TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithObjectManager) {
  Interface interface;
  interface.name = "org.chromium.Itf1";
  interface.path = "/org/chromium/Test/Object";
  interface.signals.emplace_back("Closer");
  interface.properties.emplace_back("Data", "s", "read");
  interface.properties.emplace_back("Name", "s", "readwrite");
  Interface interface2;
  interface2.name = "org.chromium.Itf2";
  vector<Interface> interfaces{interface, interface2};
  base::FilePath output_path = temp_dir_.GetPath().Append("output3.h");
  ServiceConfig config;
  config.object_manager.name = "org.chromium.ObjectManager";
  config.object_manager.object_path = "/org/chromium/Test";
  ProxyGenerator gen;
  EXPECT_TRUE(gen.GenerateProxies(config, interfaces, output_path));
  string contents;
  EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
  // The header guards contain the (temporary) filename, so we search for
  // the content we need within the string.
  test_utils::EXPECT_TEXT_CONTAINED(kExpectedContentWithObjectManager,
                                    contents);
}

TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithObjectManagerAndServiceName) {
  Interface interface;
  interface.name = "org.chromium.Itf1";
  interface.path = "/org/chromium/Test/Object";
  interface.signals.emplace_back("Closer");
  Interface interface2;
  interface2.name = "org.chromium.Itf2";
  vector<Interface> interfaces{interface, interface2};
  base::FilePath output_path = temp_dir_.GetPath().Append("output4.h");
  ServiceConfig config;
  config.service_name = "org.chromium.Test";
  config.object_manager.name = "org.chromium.ObjectManager";
  config.object_manager.object_path = "/org/chromium/Test";
  ProxyGenerator gen;
  EXPECT_TRUE(gen.GenerateProxies(config, interfaces, output_path));
  string contents;
  EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
  // The header guards contain the (temporary) filename, so we search for
  // the content we need within the string.
  test_utils::EXPECT_TEXT_CONTAINED(
      kExpectedContentWithObjectManagerAndServiceName, contents);
}

TEST_F(ProxyGeneratorTest, NewFileDescriptors) {
  Interface interface;
  interface.name = "org.chromium.TestInterface";
  interface.path = "/org/chromium/Test";
  interface.methods.emplace_back("WrapFileDescriptor",
                                 vector<Interface::Argument>{{"", "h"}},
                                 vector<Interface::Argument>{{"", "h"}});
  interface.signals.emplace_back("File",
                                 vector<Interface::Argument>{{"", "h"}});
  base::FilePath output_path = temp_dir_.GetPath().Append("output2.h");
  ServiceConfig config;
  ProxyGenerator gen;
  EXPECT_TRUE(gen.GenerateProxies(config, {interface}, output_path));
  string contents;
  EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
  // The header guards contain the (temporary) filename, so we search for
  // the content we need within the string.
  test_utils::EXPECT_TEXT_CONTAINED(kExpectedContentNewFileDescriptors,
                                    contents);
}

}  // namespace chromeos_dbus_bindings
