// 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/adaptor_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/test_utils.h"

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

namespace chromeos_dbus_bindings {

namespace {

const char kDBusTypeArryOfObjects[] = "ao";
const char kDBusTypeBool[] = "b";
const char kDBusTypeInt32[] = "i";
const char kDBusTypeInt64[] = "x";
const char kDBusTypeString[] = "s";
const char kDBusTypeFileDescriptor[] = "h";

const char kPropertyAccessReadOnly[] = "read";
const char kPropertyAccessReadWrite[] = "readwrite";

const char kInterfaceName[] = "org.chromium.Test";
const char kInterfaceName2[] = "org.chromium.Test2";

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

#include <base/files/scoped_file.h>
#include <base/macros.h>
#include <dbus/object_path.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_object.h>
#include <brillo/dbus/exported_object_manager.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/variant_dictionary.h>

namespace org {
namespace chromium {

// Interface definition for org::chromium::Test.
class TestInterface {
 public:
  virtual ~TestInterface() = default;

  virtual bool Kaneda(
      brillo::ErrorPtr* error,
      dbus::Message* message,
      const std::string& in_iwata,
      const std::vector<dbus::ObjectPath>& in_clarke,
      std::string* out_3) = 0;
  virtual bool Tetsuo(
      brillo::ErrorPtr* error,
      int32_t in_1,
      int64_t* out_2) = 0;
  virtual bool Kei(
      brillo::ErrorPtr* error) = 0;
  virtual bool Kiyoko(
      brillo::ErrorPtr* error,
      int64_t* out_akira,
      std::string* out_2) = 0;
  virtual bool Takashi(
      brillo::ErrorPtr* error,
      const Onishi& in_onishi,
      Miyako* out_miyako) = 0;
};

// Interface adaptor for org::chromium::Test.
class TestAdaptor {
 public:
  TestAdaptor(TestInterface* interface) : interface_(interface) {}

  void RegisterWithDBusObject(brillo::dbus_utils::DBusObject* object) {
    brillo::dbus_utils::DBusInterface* itf =
        object->AddOrGetInterface("org.chromium.Test");

    itf->AddSimpleMethodHandlerWithErrorAndMessage(
        "Kaneda",
        base::Unretained(interface_),
        &TestInterface::Kaneda);
    itf->AddSimpleMethodHandlerWithError(
        "Tetsuo",
        base::Unretained(interface_),
        &TestInterface::Tetsuo);
    itf->AddSimpleMethodHandlerWithError(
        "Kei",
        base::Unretained(interface_),
        &TestInterface::Kei);
    itf->AddSimpleMethodHandlerWithError(
        "Kiyoko",
        base::Unretained(interface_),
        &TestInterface::Kiyoko);
    itf->AddSimpleMethodHandlerWithError(
        "Takashi",
        base::Unretained(interface_),
        &TestInterface::Takashi);

    signal_Update_ = itf->RegisterSignalOfType<SignalUpdateType>("Update");
    signal_Mapping_ = itf->RegisterSignalOfType<SignalMappingType>("Mapping");

    itf->AddProperty(CharacterNameName(), &character_name_);
    write_property_.SetAccessMode(
        brillo::dbus_utils::ExportedPropertyBase::Access::kReadWrite);
    write_property_.SetValidator(
        base::Bind(&TestAdaptor::ValidateWriteProperty,
                   base::Unretained(this)));
    itf->AddProperty(WritePropertyName(), &write_property_);
  }

  void SendUpdateSignal() {
    auto signal = signal_Update_.lock();
    if (signal)
      signal->Send();
  }
  void SendMappingSignal(
      const std::string& in_key,
      const std::vector<dbus::ObjectPath>& in_2) {
    auto signal = signal_Mapping_.lock();
    if (signal)
      signal->Send(in_key, in_2);
  }

  static const char* CharacterNameName() { return "CharacterName"; }
  std::string GetCharacterName() const {
    return character_name_.GetValue().Get<std::string>();
  }
  void SetCharacterName(const std::string& character_name) {
    character_name_.SetValue(character_name);
  }

  static const char* WritePropertyName() { return "WriteProperty"; }
  std::string GetWriteProperty() const {
    return write_property_.GetValue().Get<std::string>();
  }
  void SetWriteProperty(const std::string& write_property) {
    write_property_.SetValue(write_property);
  }
  virtual bool ValidateWriteProperty(
      brillo::ErrorPtr* /*error*/, const std::string& /*value*/) {
    return true;
  }

  static dbus::ObjectPath GetObjectPath() {
    return dbus::ObjectPath{"/org/chromium/Test"};
  }

  static const char* GetIntrospectionXml() {
    return
        "  <interface name=\"org.chromium.Test\">\n"
        "    <method name=\"Kaneda\">\n"
        "      <arg name=\"iwata\" type=\"s\" direction=\"in\"/>\n"
        "      <arg name=\"clarke\" type=\"ao\" direction=\"in\"/>\n"
        "      <arg name=\"\" type=\"s\" direction=\"out\"/>\n"
        "    </method>\n"
        "    <method name=\"Tetsuo\">\n"
        "      <arg name=\"\" type=\"i\" direction=\"in\"/>\n"
        "      <arg name=\"\" type=\"x\" direction=\"out\"/>\n"
        "    </method>\n"
        "    <method name=\"Kei\">\n"
        "    </method>\n"
        "    <method name=\"Kiyoko\">\n"
        "      <arg name=\"akira\" type=\"x\" direction=\"out\"/>\n"
        "      <arg name=\"\" type=\"s\" direction=\"out\"/>\n"
        "    </method>\n"
        "    <method name=\"Takashi\">\n"
        "      <arg name=\"onishi\" type=\"ay\" direction=\"in\"/>\n"
        "      <arg name=\"miyako\" type=\"ay\" direction=\"out\"/>\n"
        "    </method>\n"
        "    <signal name=\"Update\">\n"
        "    </signal>\n"
        "    <signal name=\"Mapping\">\n"
        "      <arg name=\"key\" type=\"s\"/>\n"
        "      <arg name=\"\" type=\"ao\"/>\n"
        "    </signal>\n"
        "  </interface>\n";
  }

 private:
  using SignalUpdateType = brillo::dbus_utils::DBusSignal<>;
  std::weak_ptr<SignalUpdateType> signal_Update_;

  using SignalMappingType = brillo::dbus_utils::DBusSignal<
      std::string /*key*/,
      std::vector<dbus::ObjectPath>>;
  std::weak_ptr<SignalMappingType> signal_Mapping_;

  brillo::dbus_utils::ExportedProperty<std::string> character_name_;
  brillo::dbus_utils::ExportedProperty<std::string> write_property_;

  TestInterface* interface_;  // Owned by container of this adapter.

  DISALLOW_COPY_AND_ASSIGN(TestAdaptor);
};

}  // namespace chromium
}  // namespace org

namespace org {
namespace chromium {

// Interface definition for org::chromium::Test2.
class Test2Interface {
 public:
  virtual ~Test2Interface() = default;

  virtual std::string Kaneda2(
      const std::string& in_iwata) const = 0;
  virtual void Tetsuo2(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<int64_t>> response,
      int32_t in_1) = 0;
  virtual void Kei2(
      std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<bool>> response,
      dbus::Message* message) = 0;
};

// Interface adaptor for org::chromium::Test2.
class Test2Adaptor {
 public:
  Test2Adaptor(Test2Interface* interface) : interface_(interface) {}

  void RegisterWithDBusObject(brillo::dbus_utils::DBusObject* object) {
    brillo::dbus_utils::DBusInterface* itf =
        object->AddOrGetInterface("org.chromium.Test2");

    itf->AddSimpleMethodHandler(
        "Kaneda2",
        base::Unretained(interface_),
        &Test2Interface::Kaneda2);
    itf->AddMethodHandler(
        "Tetsuo2",
        base::Unretained(interface_),
        &Test2Interface::Tetsuo2);
    itf->AddMethodHandlerWithMessage(
        "Kei2",
        base::Unretained(interface_),
        &Test2Interface::Kei2);
  }

  static const char* GetIntrospectionXml() {
    return
        "  <interface name=\"org.chromium.Test2\">\n"
        "    <method name=\"Kaneda2\">\n"
        "      <arg name=\"iwata\" type=\"s\" direction=\"in\"/>\n"
        "      <arg name=\"\" type=\"s\" direction=\"out\"/>\n"
        "    </method>\n"
        "    <method name=\"Tetsuo2\">\n"
        "      <arg name=\"\" type=\"i\" direction=\"in\"/>\n"
        "      <arg name=\"\" type=\"x\" direction=\"out\"/>\n"
        "    </method>\n"
        "    <method name=\"Kei2\">\n"
        "      <arg name=\"\" type=\"b\" direction=\"out\"/>\n"
        "    </method>\n"
        "  </interface>\n";
  }

 private:
  Test2Interface* interface_;  // Owned by container of this adapter.

  DISALLOW_COPY_AND_ASSIGN(Test2Adaptor);
};

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

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

#include <base/files/scoped_file.h>
#include <base/macros.h>
#include <dbus/object_path.h>
#include <brillo/any.h>
#include <brillo/dbus/dbus_object.h>
#include <brillo/dbus/exported_object_manager.h>
#include <brillo/dbus/file_descriptor.h>
#include <brillo/variant_dictionary.h>

namespace org {
namespace chromium {

// Interface definition for org::chromium::Test.
class TestInterface {
 public:
  virtual ~TestInterface() = default;

  virtual bool WrapFileDescriptor(
      brillo::ErrorPtr* error,
      const base::ScopedFD& in_1,
      brillo::dbus_utils::FileDescriptor* out_2) = 0;
};

// Interface adaptor for org::chromium::Test.
class TestAdaptor {
 public:
  TestAdaptor(TestInterface* interface) : interface_(interface) {}

  void RegisterWithDBusObject(brillo::dbus_utils::DBusObject* object) {
    brillo::dbus_utils::DBusInterface* itf =
        object->AddOrGetInterface("org.chromium.Test");

    itf->AddSimpleMethodHandlerWithError(
        "WrapFileDescriptor",
        base::Unretained(interface_),
        &TestInterface::WrapFileDescriptor);

    signal_File_ = itf->RegisterSignalOfType<SignalFileType>("File");
  }

  void SendFileSignal(
      const brillo::dbus_utils::FileDescriptor& in_1) {
    auto signal = signal_File_.lock();
    if (signal)
      signal->Send(in_1);
  }

  static dbus::ObjectPath GetObjectPath() {
    return dbus::ObjectPath{"/org/chromium/Test"};
  }

  static const char* GetIntrospectionXml() {
    return
        "  <interface name=\"org.chromium.Test\">\n"
        "    <method name=\"WrapFileDescriptor\">\n"
        "      <arg name=\"\" type=\"h\" direction=\"in\"/>\n"
        "      <arg name=\"\" type=\"h\" direction=\"out\"/>\n"
        "    </method>\n"
        "    <signal name=\"File\">\n"
        "      <arg name=\"\" type=\"h\"/>\n"
        "    </signal>\n"
        "  </interface>\n";
  }

 private:
  using SignalFileType = brillo::dbus_utils::DBusSignal<
      brillo::dbus_utils::FileDescriptor>;
  std::weak_ptr<SignalFileType> signal_File_;

  TestInterface* interface_;  // Owned by container of this adapter.

  DISALLOW_COPY_AND_ASSIGN(TestAdaptor);
};

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

}  // namespace
class AdaptorGeneratorTest : 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(AdaptorGeneratorTest, GenerateAdaptors) {
  Interface interface;
  interface.name = kInterfaceName;
  interface.path = "/org/chromium/Test";
  interface.methods.emplace_back(
      "Kaneda",
      vector<Interface::Argument>{
          {"iwata", kDBusTypeString},
          {"clarke", kDBusTypeArryOfObjects}},
      vector<Interface::Argument>{{"", kDBusTypeString}});
  interface.methods.back().include_dbus_message = true;
  interface.methods.emplace_back(
      "Tetsuo",
      vector<Interface::Argument>{{"", kDBusTypeInt32}},
      vector<Interface::Argument>{{"", kDBusTypeInt64}});
  interface.methods.emplace_back("Kei");
  // Interface methods with more than one return argument should be ignored.
  interface.methods.emplace_back(
      "Kiyoko",
      vector<Interface::Argument>{},
      vector<Interface::Argument>{
          {"akira", kDBusTypeInt64},
          {"", kDBusTypeString}});

  // Interface methods with protobuf class.
  interface.methods.emplace_back(
      "Takashi",
      vector<Interface::Argument>{
          {"onishi", string(kProtobufType)+"Onishi"}},
      vector<Interface::Argument>{
          {"miyako", string(kProtobufType)+"Miyako"}});

  // Signals generate helper methods to send them.
  interface.signals.emplace_back(
      "Update",
      vector<Interface::Argument>{});
  interface.signals.emplace_back(
      "Mapping",
      vector<Interface::Argument>{
          {"key", kDBusTypeString},
          {"", kDBusTypeArryOfObjects}});
  interface.properties.emplace_back(
      "CharacterName",
      kDBusTypeString,
      kPropertyAccessReadOnly);
  interface.properties.emplace_back(
      "WriteProperty",
      kDBusTypeString,
      kPropertyAccessReadWrite);

  Interface interface2;
  interface2.name = kInterfaceName2;
  interface2.methods.emplace_back(
      "Kaneda2",
      vector<Interface::Argument>{{"iwata", kDBusTypeString}},
      vector<Interface::Argument>{{"", kDBusTypeString}});
  interface2.methods.back().is_const = true;
  interface2.methods.back().kind = Interface::Method::Kind::kSimple;
  interface2.methods.emplace_back(
      "Tetsuo2",
      vector<Interface::Argument>{{"", kDBusTypeInt32}},
      vector<Interface::Argument>{{"", kDBusTypeInt64}});
  interface2.methods.back().kind = Interface::Method::Kind::kAsync;
  interface2.methods.emplace_back(
      "Kei2",
      vector<Interface::Argument>{},
      vector<Interface::Argument>{{"", kDBusTypeBool}});
  interface2.methods.back().kind = Interface::Method::Kind::kAsync;
  interface2.methods.back().include_dbus_message = true;

  base::FilePath output_path = temp_dir_.GetPath().Append("output.h");
  AdaptorGenerator gen;
  EXPECT_TRUE(gen.GenerateAdaptors({interface, interface2}, 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(kGenerateAdaptorsOutput, contents);
}

TEST_F(AdaptorGeneratorTest, NewFileDescriptors) {
  Interface interface;
  interface.name = kInterfaceName;
  interface.path = "/org/chromium/Test";
  interface.methods.emplace_back(
      "WrapFileDescriptor",
      vector<Interface::Argument>{{"", kDBusTypeFileDescriptor}},
      vector<Interface::Argument>{{"", kDBusTypeFileDescriptor}});
  interface.signals.emplace_back(
      "File",
      vector<Interface::Argument>{{"", kDBusTypeFileDescriptor}});

  base::FilePath output_path = temp_dir_.GetPath().Append("output2.h");
  AdaptorGenerator gen;
  EXPECT_TRUE(gen.GenerateAdaptors({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(kNewFileDescriptorsOutput, contents);
}

}  // namespace chromeos_dbus_bindings
