// 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 <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <brillo/strings/string_utils.h>

#include "chromeos-dbus-bindings/dbus_signature.h"
#include "chromeos-dbus-bindings/header_generator.h"
#include "chromeos-dbus-bindings/indented_text.h"
#include "chromeos-dbus-bindings/interface.h"
#include "chromeos-dbus-bindings/name_parser.h"

using base::StringPrintf;
using std::string;
using std::vector;

namespace chromeos_dbus_bindings {

AdaptorGenerator::AdaptorGenerator() = default;

bool AdaptorGenerator::GenerateAdaptors(
    const std::vector<Interface>& interfaces,
    const base::FilePath& output_file) {
  IndentedText text;
  CHECK(!interfaces.empty()) << "At least one interface must be provided";

  text.AddLine("// Automatic generation of D-Bus interfaces:");
  for (const auto& interface : interfaces) {
    text.AddLine(StringPrintf("//  - %s", interface.name.c_str()));
  }
  string header_guard = GenerateHeaderGuard(output_file);
  text.AddLine(StringPrintf("#ifndef %s", header_guard.c_str()));
  text.AddLine(StringPrintf("#define %s", header_guard.c_str()));
  text.AddLine("#include <memory>");
  text.AddLine("#include <string>");
  text.AddLine("#include <tuple>");
  text.AddLine("#include <vector>");
  text.AddBlankLine();
  text.AddLine("#include <base/files/scoped_file.h>");
  text.AddLine("#include <base/macros.h>");
  text.AddLine("#include <dbus/object_path.h>");
  text.AddLine("#include <brillo/any.h>");
  text.AddLine("#include <brillo/dbus/dbus_object.h>");
  text.AddLine("#include <brillo/dbus/exported_object_manager.h>");
  text.AddLine("#include <brillo/dbus/file_descriptor.h>");
  text.AddLine("#include <brillo/variant_dictionary.h>");

  for (const auto& interface : interfaces)
    GenerateInterfaceAdaptor(interface, &text);

  text.AddLine(StringPrintf("#endif  // %s", header_guard.c_str()));

  return WriteTextToFile(output_file, text);
}

void AdaptorGenerator::GenerateInterfaceAdaptor(
    const Interface& interface,
    IndentedText *text) {
  NameParser parser{interface.name};
  string itf_name = parser.MakeInterfaceName(false);
  string class_name = parser.MakeAdaptorName(false);
  string full_itf_name = parser.MakeFullCppName();

  text->AddBlankLine();
  parser.AddOpenNamespaces(text, false);

  text->AddBlankLine();
  text->AddLine(StringPrintf("// Interface definition for %s.",
                             full_itf_name.c_str()));
  text->AddComments(interface.doc_string);
  text->AddLine(StringPrintf("class %s {", itf_name.c_str()));
  text->AddLineWithOffset("public:", kScopeOffset);
  text->PushOffset(kBlockOffset);
  text->AddLine(StringPrintf("virtual ~%s() = default;", itf_name.c_str()));
  AddInterfaceMethods(interface, text);
  text->PopOffset();
  text->AddLine("};");

  text->AddBlankLine();
  text->AddLine(StringPrintf("// Interface adaptor for %s.",
                             full_itf_name.c_str()));
  text->AddLine(StringPrintf("class %s {", class_name.c_str()));
  text->AddLineWithOffset("public:", kScopeOffset);
  text->PushOffset(kBlockOffset);
  AddConstructor(interface, class_name, itf_name, text);
  AddRegisterWithDBusObject(itf_name, interface, text);
  AddSendSignalMethods(interface, text);
  AddPropertyMethodImplementation(interface, text);
  if (!interface.path.empty()) {
    text->AddBlankLine();
    text->AddLine("static dbus::ObjectPath GetObjectPath() {");
    text->PushOffset(kBlockOffset);
    text->AddLine(StringPrintf("return dbus::ObjectPath{\"%s\"};",
                               interface.path.c_str()));
    text->PopOffset();
    text->AddLine("}");
  }
  text->PopOffset();

  text->AddBlankLine();
  text->AddLineWithOffset("private:", kScopeOffset);
  text->PushOffset(kBlockOffset);
  AddSignalDataMembers(interface, text);
  AddPropertyDataMembers(interface, text);

  if (!interface.methods.empty()) {
    text->AddLine(StringPrintf(
        "%s* interface_;  // Owned by container of this adapter.",
        itf_name.c_str()));
  }

  text->AddBlankLine();
  text->AddLine(StringPrintf("DISALLOW_COPY_AND_ASSIGN(%s);",
                             class_name.c_str()));
  text->PopOffset();
  text->AddLine("};");

  text->AddBlankLine();
  parser.AddCloseNamespaces(text, false);
}

void AdaptorGenerator::AddConstructor(const Interface& interface,
                                      const string& class_name,
                                      const string& itf_name,
                                      IndentedText *text) {
  if (interface.methods.empty()) {
    text->AddLine(StringPrintf("%s(%s* /* interface */) {}",
                               class_name.c_str(), itf_name.c_str()));

  } else {
    text->AddLine(StringPrintf("%s(%s* interface) : interface_(interface) {}",
                               class_name.c_str(), itf_name.c_str()));
  }
}

void AdaptorGenerator::AddRegisterWithDBusObject(
    const std::string& itf_name,
    const Interface& interface,
    IndentedText *text) {
  text->AddBlankLine();
  text->AddLine(
    "void RegisterWithDBusObject(brillo::dbus_utils::DBusObject* object) {");
  text->PushOffset(kBlockOffset);
  text->AddLine("brillo::dbus_utils::DBusInterface* itf =");
  text->AddLineWithOffset(
      StringPrintf("object->AddOrGetInterface(\"%s\");",
                   interface.name.c_str()), kLineContinuationOffset);
  RegisterInterface(itf_name, interface, text);
  text->PopOffset();
  text->AddLine("}");
}

void AdaptorGenerator::RegisterInterface(const string& itf_name,
                                         const Interface& interface,
                                         IndentedText *text) {
  if (!interface.methods.empty())
    text->AddBlankLine();
  for (const auto& method : interface.methods) {
    string add_handler_name;
    switch (method.kind) {
      case Interface::Method::Kind::kSimple:
        add_handler_name = "AddSimpleMethodHandler";
        break;
      case Interface::Method::Kind::kNormal:
        if (method.include_dbus_message)
          add_handler_name = "AddSimpleMethodHandlerWithErrorAndMessage";
        else
          add_handler_name = "AddSimpleMethodHandlerWithError";
        break;
      case Interface::Method::Kind::kAsync:
        if (method.include_dbus_message)
          add_handler_name = "AddMethodHandlerWithMessage";
        else
          add_handler_name = "AddMethodHandler";
        break;
      case Interface::Method::Kind::kRaw:
        add_handler_name = "AddRawMethodHandler";
        break;
    }

    text->AddLine(StringPrintf("itf->%s(", add_handler_name.c_str()));
    text->PushOffset(kLineContinuationOffset);
    text->AddLine(StringPrintf("\"%s\",", method.name.c_str()));
    text->AddLine("base::Unretained(interface_),");
    text->AddLine(StringPrintf("&%s::%s);", itf_name.c_str(),
                               method.name.c_str()));
    text->PopOffset();
  }

  // Register signals.
  if (!interface.signals.empty())
    text->AddBlankLine();
  for (const auto& signal : interface.signals) {
    string signal_var_name = StringPrintf("signal_%s_", signal.name.c_str());
    string signal_type_name = StringPrintf("Signal%sType", signal.name.c_str());
    text->AddLine(StringPrintf("%s = itf->RegisterSignalOfType<%s>(\"%s\");",
                               signal_var_name.c_str(),
                               signal_type_name.c_str(),
                               signal.name.c_str()));
  }

  // Register exported properties.
  if (!interface.properties.empty())
    text->AddBlankLine();
  for (const auto& property : interface.properties) {
    string variable_name = NameParser{property.name}.MakeVariableName();
    string write_access;
    if (property.access == "write") {
      write_access = "kWriteOnly";
    } else if (property.access == "readwrite") {
      write_access = "kReadWrite";
    }
    if (!write_access.empty()) {
      text->AddLine(StringPrintf("%s_.SetAccessMode(", variable_name.c_str()));
      text->PushOffset(kLineContinuationOffset);
      text->AddLine(
          StringPrintf(
              "brillo::dbus_utils::ExportedPropertyBase::Access::%s);",
              write_access.c_str()));
      text->PopOffset();
      text->AddLine(StringPrintf("%s_.SetValidator(", variable_name.c_str()));
      text->PushOffset(kLineContinuationOffset);
      text->AddLineAndPushOffsetTo(
          StringPrintf(
              "base::Bind(&%s::Validate%s,",
              NameParser{interface.name}.MakeAdaptorName(false).c_str(),
              property.name.c_str()),
          1, '(');
      text->AddLine("base::Unretained(this)));");
      text->PopOffset();
      text->PopOffset();
    }
    text->AddLine(StringPrintf("itf->AddProperty(%sName(), &%s_);",
                               property.name.c_str(), variable_name.c_str()));
  }
}

void AdaptorGenerator::AddInterfaceMethods(const Interface& interface,
                                           IndentedText *text) {
  IndentedText block;
  DBusSignature signature;
  if (!interface.methods.empty())
    block.AddBlankLine();

  for (const auto& method : interface.methods) {
    string const_method;
    if (method.is_const)
      const_method = " const";

    string return_type = "void";
    vector<string> method_params;
    auto input_arguments_copy = method.input_arguments;
    auto output_arguments_copy = method.output_arguments;
    switch (method.kind) {
      case Interface::Method::Kind::kSimple:
        if (output_arguments_copy.size() == 1) {
          auto type = signature.Parse(output_arguments_copy[0].type);
          CHECK(type);
          return_type = type->GetBaseType(DBusType::Direction::kAppend);
          output_arguments_copy.clear();
        }
        break;
      case Interface::Method::Kind::kNormal:
        method_params.push_back("brillo::ErrorPtr* error");
        if (method.include_dbus_message)
          method_params.push_back("dbus::Message* message");
        return_type = "bool";
        break;
      case Interface::Method::Kind::kAsync: {
        std::vector<std::string> out_types;
        for (const auto& argument : output_arguments_copy) {
          auto type = signature.Parse(argument.type);
          CHECK(type);
          out_types.push_back(type->GetBaseType(DBusType::Direction::kAppend));
        }
        method_params.push_back(base::StringPrintf(
            "std::unique_ptr<brillo::dbus_utils::DBusMethodResponse<%s>> "
            "response",
             brillo::string_utils::Join(", ", out_types).c_str()));
        if (method.include_dbus_message)
          method_params.push_back("dbus::Message* message");
        output_arguments_copy.clear();
        break;
      }
      case Interface::Method::Kind::kRaw:
        method_params.push_back("dbus::MethodCall* method_call");
        method_params.push_back("brillo::dbus_utils::ResponseSender sender");
        // Raw methods don't take static parameters or return values directly.
        input_arguments_copy.clear();
        output_arguments_copy.clear();
        break;
    }
    block.AddComments(method.doc_string);
    string method_start = StringPrintf("virtual %s %s(",
                                       return_type.c_str(),
                                       method.name.c_str());
    string method_end = StringPrintf(")%s = 0;", const_method.c_str());
    int index = 0;
    for (const auto& argument : input_arguments_copy) {
      auto type = signature.Parse(argument.type);
      CHECK(type);
      string param_type = type->GetInArgType(DBusType::Receiver::kAdaptor);
      string param_name = GetArgName("in", argument.name, ++index);
      method_params.push_back(param_type + ' ' + param_name);
    }

    for (const auto& argument : output_arguments_copy) {
      auto type = signature.Parse(argument.type);
      CHECK(type);
      string param_type = type->GetOutArgType(DBusType::Receiver::kAdaptor);
      string param_name = GetArgName("out", argument.name, ++index);
      method_params.push_back(param_type + ' ' + param_name);
    }

    if (method_params.empty()) {
      block.AddLine(method_start + method_end);
    } else {
      block.AddLine(method_start);
      block.PushOffset(kLineContinuationOffset);
      for (size_t i = 0; i < method_params.size() - 1; i++)
        block.AddLine(method_params[i] + ',');
      block.AddLine(method_params.back() + method_end);
      block.PopOffset();
    }
  }
  text->AddBlock(block);
}

void AdaptorGenerator::AddSendSignalMethods(
    const Interface& interface,
    IndentedText *text) {
  IndentedText block;
  DBusSignature signature;

  if (!interface.signals.empty())
    block.AddBlankLine();

  for (const auto& signal : interface.signals) {
    block.AddComments(signal.doc_string);
    string method_start = StringPrintf("void Send%sSignal(",
                                       signal.name.c_str());
    string method_end = ") {";

    int index = 0;
    vector<string> method_params;
    vector<string> param_names;
    for (const auto& argument : signal.arguments) {
      auto type = signature.Parse(argument.type);
      CHECK(type);
      // We are the sender for signals, so pretend we're a proxy
      // when generating the type.
      string param_type = type->GetInArgType(DBusType::Receiver::kProxy);
      string param_name = GetArgName("in", argument.name, ++index);
      param_names.push_back(param_name);
      method_params.push_back(param_type + ' ' + param_name);
    }

    if (method_params.empty()) {
      block.AddLine(method_start + method_end);
    } else {
      block.AddLine(method_start);
      block.PushOffset(kLineContinuationOffset);
      for (size_t i = 0; i < method_params.size() - 1; i++)
        block.AddLine(method_params[i] + ',');
      block.AddLine(method_params.back() + method_end);
      block.PopOffset();
    }

    string args = brillo::string_utils::Join(", ", param_names);
    block.PushOffset(kBlockOffset);
    block.AddLine(StringPrintf("auto signal = signal_%s_.lock();",
                                signal.name.c_str()));
    block.AddLine("if (signal)");
    block.AddLineWithOffset(StringPrintf("signal->Send(%s);", args.c_str()),
                            kBlockOffset);
    block.PopOffset();
    block.AddLine("}");
  }
  text->AddBlock(block);
}

void AdaptorGenerator::AddSignalDataMembers(const Interface& interface,
                                            IndentedText *text) {
  IndentedText block;
  DBusSignature signature;

  for (const auto& signal : interface.signals) {
    string signal_type_name = StringPrintf("Signal%sType", signal.name.c_str());
    string signal_type_alias_begin =
        StringPrintf("using %s = brillo::dbus_utils::DBusSignal<",
                     signal_type_name.c_str());
    string signal_type_alias_end = ">;";
    vector<string> params;
    for (const auto& argument : signal.arguments) {
      auto type = signature.Parse(argument.type);
      CHECK(type);
      string param = type->GetBaseType(DBusType::Direction::kAppend);
      if (!argument.name.empty())
        base::StringAppendF(&param, " /*%s*/", argument.name.c_str());
      params.push_back(param);
    }
    if (params.empty()) {
      block.AddLine(signal_type_alias_begin + signal_type_alias_end);
    } else {
      block.AddLine(signal_type_alias_begin);
      block.PushOffset(kLineContinuationOffset);
      for (size_t i = 0; i < params.size() - 1; i++)
        block.AddLine(params[i] + ',');
      block.AddLine(params.back() + signal_type_alias_end);
      block.PopOffset();
    }
    block.AddLine(
        StringPrintf("std::weak_ptr<%s> signal_%s_;",
                      signal_type_name.c_str(), signal.name.c_str()));
    block.AddBlankLine();
  }
  text->AddBlock(block);
}

void AdaptorGenerator::AddPropertyMethodImplementation(
    const Interface& interface,
    IndentedText *text) {
  IndentedText block;
  DBusSignature signature;

  for (const auto& property : interface.properties) {
    block.AddBlankLine();
    auto parsed_type = signature.Parse(property.type);
    CHECK(parsed_type && parsed_type->IsValidPropertyType());
    string type = parsed_type->GetBaseType(DBusType::Direction::kExtract);
    string variable_name = NameParser{property.name}.MakeVariableName();

    // Property name accessor.
    block.AddComments(property.doc_string);
    block.AddLine(StringPrintf("static const char* %sName() { return \"%s\"; }",
                               property.name.c_str(), property.name.c_str()));

    // Getter method.
    block.AddLine(StringPrintf("%s Get%s() const {",
                               type.c_str(),
                               property.name.c_str()));
    block.PushOffset(kBlockOffset);
    block.AddLine(StringPrintf("return %s_.GetValue().Get<%s>();",
                               variable_name.c_str(),
                               type.c_str()));
    block.PopOffset();
    block.AddLine("}");

    // Setter method.
    type = parsed_type->GetInArgType(DBusType::Receiver::kAdaptor);
    block.AddLine(StringPrintf("void Set%s(%s %s) {",
                               property.name.c_str(),
                               type.c_str(),
                               variable_name.c_str()));
    block.PushOffset(kBlockOffset);
    block.AddLine(StringPrintf("%s_.SetValue(%s);",
                               variable_name.c_str(),
                               variable_name.c_str()));
    block.PopOffset();
    block.AddLine("}");

    // Validation method for property with write access.
    if (property.access != "read") {
      block.AddLine(StringPrintf("virtual bool Validate%s(",
                                 property.name.c_str()));
      block.PushOffset(kLineContinuationOffset);
      // Explicitly specify the "value" parameter as const & to match the
      // validator callback function signature.
      type = parsed_type->GetBaseType(DBusType::Direction::kExtract);
      block.AddLine(
          StringPrintf(
              "brillo::ErrorPtr* /*error*/, const %s& /*value*/) {",
              type.c_str()));
      block.PopOffset();
      block.PushOffset(kBlockOffset);
      block.AddLine("return true;");
      block.PopOffset();
      block.AddLine("}");
    }
  }
  text->AddBlock(block);
}

void AdaptorGenerator::AddPropertyDataMembers(const Interface& interface,
                                              IndentedText *text) {
  IndentedText block;
  DBusSignature signature;

  for (const auto& property : interface.properties) {
    auto parsed_type = signature.Parse(property.type);
    CHECK(parsed_type && parsed_type->IsValidPropertyType());
    string type = parsed_type->GetBaseType(DBusType::Direction::kExtract);
    string variable_name = NameParser{property.name}.MakeVariableName();

    block.AddLine(
        StringPrintf("brillo::dbus_utils::ExportedProperty<%s> %s_;",
                     type.c_str(), variable_name.c_str()));
  }
  if (!interface.properties.empty())
    block.AddBlankLine();

  text->AddBlock(block);
}

}  // namespace chromeos_dbus_bindings
