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

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/check.h>
#include <base/check_op.h>
#include <base/logging.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <dbus/dbus-protocol.h>

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

namespace chromeos_dbus_bindings {

std::string DBusType::GetOutArgType(Receiver receiver) const {
  return GetBaseType(receiver == Receiver::kAdaptor ? Direction::kAppend
                                                    : Direction::kExtract) +
         "*";
}

namespace {

// Limit the maximum allowed parsing depth, to prevent stack overflow.
const int kMaxDepth = 100;

// DBusType representing simple numeric types, such as int.
class Scalar : public DBusType {
 public:
  enum class Type {
    kBoolean,
    kByte,
    kDouble,
    kInt16,
    kInt32,
    kInt64,
    kUint16,
    kUint32,
    kUint64,
  };

  explicit Scalar(Type type) : type_(type) {}
  Scalar(const Scalar&) = delete;
  Scalar& operator=(const Scalar&) = delete;

  bool IsValidPropertyType() const override { return true; }

  std::string GetBaseType(Direction direction) const override {
    switch (type_) {
      case Type::kBoolean:
        return "bool";
      case Type::kByte:
        return "uint8_t";
      case Type::kDouble:
        return "double";
      case Type::kInt16:
        return "int16_t";
      case Type::kInt32:
        return "int32_t";
      case Type::kInt64:
        return "int64_t";
      case Type::kUint16:
        return "uint16_t";
      case Type::kUint32:
        return "uint32_t";
      case Type::kUint64:
        return "uint64_t";
    }
  }

  std::string GetInArgType(Receiver receiver) const override {
    return GetBaseType(receiver == Receiver::kAdaptor ? Direction::kExtract
                                                      : Direction::kAppend);
  }

  std::string GetCallbackArgType() const override {
    return GetBaseType(Direction::kExtract);
  }

 private:
  Type type_;
};

// DBusType representing argument types that correspond to C++ objects.
// Example would be brillo::Any or std::map.
class NonScalar : public DBusType {
 public:
  std::string GetInArgType(Receiver receiver) const override {
    return base::StringPrintf(
        "const %s&",
        GetBaseType(receiver == Receiver::kAdaptor ? Direction::kExtract
                                                   : Direction::kAppend)
            .c_str());
  }

  std::string GetCallbackArgType() const override {
    return base::StringPrintf("const %s&",
                              GetBaseType(Direction::kExtract).c_str());
  }
};

class SimpleNonScalar : public NonScalar {
 public:
  enum class Type {
    kObjectPath,
    kString,
    kVariant,
    kVariantDict,
  };

  explicit SimpleNonScalar(Type type) : type_(type) {}
  SimpleNonScalar(const SimpleNonScalar&) = delete;
  SimpleNonScalar& operator=(const SimpleNonScalar&) = delete;

  bool IsValidPropertyType() const override { return true; }

  std::string GetBaseType(Direction direction) const override {
    switch (type_) {
      case Type::kObjectPath:
        return "dbus::ObjectPath";
      case Type::kString:
        return "std::string";
      case Type::kVariant:
        return "brillo::Any";
      case Type::kVariantDict:
        return "brillo::VariantDictionary";
    }
  }

 private:
  Type type_;
};

class FileDescriptor : public NonScalar {
 public:
  bool IsValidPropertyType() const override { return false; }

  std::string GetBaseType(Direction direction) const override {
    return direction == Direction::kExtract
               ? "base::ScopedFD"
               : "brillo::dbus_utils::FileDescriptor";
  }
};

class Array : public NonScalar {
 public:
  explicit Array(std::unique_ptr<DBusType> inner_type)
      : inner_type_(std::move(inner_type)) {}
  Array(const Array&) = delete;
  Array& operator=(const Array&) = delete;

  bool IsValidPropertyType() const override {
    return inner_type_->IsValidPropertyType();
  }

  std::string GetBaseType(Direction direction) const override {
    return base::StringPrintf("std::vector<%s>",
                              inner_type_->GetBaseType(direction).c_str());
  }

 private:
  std::unique_ptr<DBusType> inner_type_;
};

class Dict : public NonScalar {
 public:
  explicit Dict(std::unique_ptr<DBusType> key_type,
                std::unique_ptr<DBusType> value_type)
      : key_type_(std::move(key_type)), value_type_(std::move(value_type)) {}
  Dict(const Dict&) = delete;
  Dict& operator=(const Dict&) = delete;

  bool IsValidPropertyType() const override {
    return key_type_->IsValidPropertyType() &&
           value_type_->IsValidPropertyType();
  }

  std::string GetBaseType(Direction direction) const override {
    return base::StringPrintf("std::map<%s, %s>",
                              key_type_->GetBaseType(direction).c_str(),
                              value_type_->GetBaseType(direction).c_str());
  }

 private:
  std::unique_ptr<DBusType> key_type_;
  std::unique_ptr<DBusType> value_type_;
};

class Struct : public NonScalar {
 public:
  explicit Struct(std::vector<std::unique_ptr<DBusType>>&& inner_types)
      : inner_types_(std::move(inner_types)) {}
  Struct(const Struct&) = delete;
  Struct& operator=(const Struct&) = delete;

  bool IsValidPropertyType() const override {
    for (const auto& child : inner_types_) {
      if (!child->IsValidPropertyType())
        return false;
    }

    return true;
  }

  std::string GetBaseType(Direction direction) const override {
    std::vector<std::string> child_types;
    for (const auto& child : inner_types_)
      child_types.push_back(child->GetBaseType(direction));
    return base::StringPrintf("std::tuple<%s>",
                              base::JoinString(child_types, ", ").c_str());
  }

 private:
  std::vector<std::unique_ptr<DBusType>> inner_types_;
};

class ProtobufClass : public NonScalar {
 public:
  explicit ProtobufClass(std::string protobuf_class)
      : protobuf_class_(protobuf_class) {}
  ProtobufClass(const ProtobufClass&) = delete;
  ProtobufClass& operator=(const ProtobufClass&) = delete;

  bool IsValidPropertyType() const override {
    // Using protobuf class for property is not yet supported.
    return false;
  }

  std::string GetBaseType(Direction direction) const override {
    return protobuf_class_;
  }

 private:
  string protobuf_class_;
};

}  // namespace

DBusSignature::DBusSignature() = default;

std::unique_ptr<DBusType> DBusSignature::Parse(const string& signature) {
  string::const_iterator end;
  auto type = GetTypenameForSignature(signature.begin(), signature.end(),
                                      /*depth=*/0, &end);
  if (!type) {
    LOG(ERROR) << "Parse failed for signature " << signature;
    return nullptr;
  }

  if (end != signature.end()) {
    LOG(WARNING) << "A portion of signature " << signature
                 << " is left unparsed: " << string(end, signature.end());
  }

  return type;
}

std::unique_ptr<DBusType> DBusSignature::GetTypenameForSignature(
    string::const_iterator signature,
    string::const_iterator end,
    int nesting_depth,
    string::const_iterator* next) {
  DCHECK(next);
  if (signature == end) {
    LOG(ERROR) << "Signature is empty";
    return nullptr;
  }

  if (nesting_depth > kMaxDepth) {
    LOG(ERROR) << "Excessive nesting depth";
    return nullptr;
  }

  string::const_iterator cur = signature;
  int signature_value = *cur++;
  std::unique_ptr<DBusType> type;
  switch (signature_value) {
    case DBUS_STRUCT_BEGIN_CHAR:
      type = GetStructTypenameForSignature(cur, end, nesting_depth, &cur);
      break;
    case DBUS_TYPE_ARRAY:
      type = GetArrayTypenameForSignature(cur, end, nesting_depth, &cur);
      break;
    case DBUS_TYPE_BOOLEAN:
      type = std::make_unique<Scalar>(Scalar::Type::kBoolean);
      break;
    case DBUS_TYPE_BYTE:
      type = std::make_unique<Scalar>(Scalar::Type::kByte);
      break;
    case DBUS_TYPE_DOUBLE:
      type = std::make_unique<Scalar>(Scalar::Type::kDouble);
      break;
    case DBUS_TYPE_OBJECT_PATH:
      type =
          std::make_unique<SimpleNonScalar>(SimpleNonScalar::Type::kObjectPath);
      break;
    case DBUS_TYPE_INT16:
      type = std::make_unique<Scalar>(Scalar::Type::kInt16);
      break;
    case DBUS_TYPE_INT32:
      type = std::make_unique<Scalar>(Scalar::Type::kInt32);
      break;
    case DBUS_TYPE_INT64:
      type = std::make_unique<Scalar>(Scalar::Type::kInt64);
      break;
    case DBUS_TYPE_STRING:
      type = std::make_unique<SimpleNonScalar>(SimpleNonScalar::Type::kString);
      break;
    case DBUS_TYPE_UNIX_FD:
      type = std::make_unique<FileDescriptor>();
      break;
    case DBUS_TYPE_UINT16:
      type = std::make_unique<Scalar>(Scalar::Type::kUint16);
      break;
    case DBUS_TYPE_UINT32:
      type = std::make_unique<Scalar>(Scalar::Type::kUint32);
      break;
    case DBUS_TYPE_UINT64:
      type = std::make_unique<Scalar>(Scalar::Type::kUint64);
      break;
    case DBUS_TYPE_VARIANT:
      type = std::make_unique<SimpleNonScalar>(SimpleNonScalar::Type::kVariant);
      break;
    case DBUS_TYPE_CHROMEOS_PROTOBUF:
      type = std::make_unique<ProtobufClass>(string(cur, end));
      cur = end;
      break;
    default:
      LOG(ERROR) << "Unexpected token " << *signature;
      return nullptr;
  }

  *next = cur;
  return type;
}

bool DBusSignature::ParseChildTypes(
    string::const_iterator signature,
    string::const_iterator end,
    string::value_type end_char,
    int nesting_depth,
    string::const_iterator* next,
    vector<std::unique_ptr<DBusType>>* children) {
  DCHECK(next);
  DCHECK(children);
  string::const_iterator cur = signature;

  while (cur != end && *cur != end_char) {
    auto child = GetTypenameForSignature(cur, end, nesting_depth + 1, &cur);
    if (!child) {
      LOG(ERROR) << "Unable to decode child elements starting at "
                 << string(cur, end);
      return false;
    }

    children->push_back(std::move(child));
  }

  if (cur == end) {
    LOG(ERROR) << "At end of string while processing container type "
               << "starting at " << string(signature, end);
    return false;
  }

  DCHECK_EQ(end_char, *cur);
  *next = cur + 1;
  return true;
}

std::unique_ptr<DBusType> DBusSignature::GetArrayTypenameForSignature(
    string::const_iterator signature,
    string::const_iterator end,
    int nesting_depth,
    string::const_iterator* next) {
  DCHECK(next);
  if (signature == end) {
    LOG(ERROR) << "At end of string while reading array parameter";
    return nullptr;
  }

  if (*signature == DBUS_DICT_ENTRY_BEGIN_CHAR)
    return GetDictTypenameForSignature(signature, end, nesting_depth, next);

  string::const_iterator cur = signature;
  auto child = GetTypenameForSignature(cur, end, nesting_depth + 1, &cur);
  if (!child) {
    LOG(ERROR) << "Unable to decode child element starting at "
               << string(cur, end);
    return nullptr;
  }

  *next = cur;
  return std::make_unique<Array>(std::move(child));
}

std::unique_ptr<DBusType> DBusSignature::GetDictTypenameForSignature(
    string::const_iterator signature,
    string::const_iterator end,
    int nesting_depth,
    string::const_iterator* next) {
  DCHECK(next);
  string::const_iterator cur = signature;

  // The dictionary entry type has to be at least 4 characters long:
  // two curly braces and two characters for the key and value types.
  if (end - cur < 4) {
    LOG(ERROR) << "Malformed dictionary at " << string(signature, end);
    return nullptr;
  }

  // Check for VariantDictionary, which is a special case.
  if (string(cur, cur + 4) == "{sv}") {
    *next = cur + 4;
    return std::make_unique<SimpleNonScalar>(
        SimpleNonScalar::Type::kVariantDict);
  }

  ++cur;

  vector<std::unique_ptr<DBusType>> children;
  if (!ParseChildTypes(cur, end, DBUS_DICT_ENTRY_END_CHAR, nesting_depth, &cur,
                       &children))
    return nullptr;

  if (children.size() != 2) {
    LOG(ERROR) << "Dict entry contains " << children.size()
               << " members starting at " << string(signature, end)
               << " but dict entries can only have 2 sub-types.";
    return nullptr;
  }

  *next = cur;
  return std::make_unique<Dict>(std::move(children[0]), std::move(children[1]));
}

std::unique_ptr<DBusType> DBusSignature::GetStructTypenameForSignature(
    string::const_iterator signature,
    string::const_iterator end,
    int nesting_depth,
    string::const_iterator* next) {
  DCHECK(next);

  if (signature == end) {
    LOG(ERROR) << "At end of string while reading struct parameter";
    return nullptr;
  }

  string::const_iterator cur = signature;
  vector<std::unique_ptr<DBusType>> children;
  if (!ParseChildTypes(cur, end, DBUS_STRUCT_END_CHAR, nesting_depth, &cur,
                       &children)) {
    return nullptr;
  }

  *next = cur;
  return std::make_unique<Struct>(std::move(children));
}

}  // namespace chromeos_dbus_bindings
