/*
 * Copyright (C) 2015, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "type_cpp.h"

#include <algorithm>
#include <iostream>
#include <vector>

#include <android-base/stringprintf.h>
#include <android-base/strings.h>

#include "logging.h"

using std::cerr;
using std::endl;
using std::set;
using std::string;
using std::unique_ptr;
using std::vector;

using android::base::Split;
using android::base::Join;
using android::base::StringPrintf;

namespace android {
namespace aidl {
namespace cpp {
namespace {

const char kNoPackage[] = "";
const char kNoHeader[] = "";
const char kNoValidMethod[] = "";
Type* const kNoArrayType = nullptr;
Type* const kNoNullableType = nullptr;

bool is_cpp_keyword(const std::string& str) {
  static const std::vector<std::string> kCppKeywords{
    "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor",
    "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
    "compl", "concept", "const", "constexpr", "const_cast", "continue",
    "decltype", "default", "delete", "do", "double", "dynamic_cast", "else",
    "enum", "explicit", "export", "extern", "false", "float", "for", "friend",
    "goto", "if", "inline", "int", "long", "mutable", "namespace", "new",
    "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
    "private", "protected", "public", "register", "reinterpret_cast",
    "requires", "return", "short", "signed", "sizeof", "static",
    "static_assert", "static_cast", "struct", "switch", "template", "this",
    "thread_local", "throw", "true", "try", "typedef", "typeid", "typename",
    "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t",
    "while", "xor", "xor_eq",
  };
  return std::find(kCppKeywords.begin(), kCppKeywords.end(), str) !=
      kCppKeywords.end();
}

class VoidType : public Type {
 public:
  VoidType() : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "void",
                    {}, "void", kNoValidMethod, kNoValidMethod) {}
  virtual ~VoidType() = default;
  bool CanBeOutParameter() const override { return false; }
  bool CanWriteToParcel() const override { return false; }
};  // class VoidType

class CppArrayType : public Type {
 public:
  CppArrayType(int kind,  // from ValidatableType
            const std::string& package,
            const string& underlying_aidl_type,
            const string& cpp_header,
            const string& underlying_cpp_type,
            const string& read_method,
            const string& write_method,
            bool is_nullable,
            const string& src_file_name = "")
      : Type(kind, package,
             underlying_aidl_type + "[]",
             GetHeaders(is_nullable, cpp_header),
             GetCppType(is_nullable, underlying_cpp_type),
             read_method, write_method, kNoArrayType,
             (is_nullable)
                 ? kNoNullableType
                 // All arrays are nullable.
                 : new CppArrayType(kind, package, underlying_aidl_type,
                                    cpp_header, underlying_cpp_type,
                                    read_method, write_method, true),
             src_file_name) {}

  bool CanBeOutParameter() const override { return true; }

 private:
  static vector<string> GetHeaders(bool is_nullable, const string& cpp_header) {
    vector<string> result = {"vector"};
    if (is_nullable) {
      result.push_back("memory");
    }
    if (!cpp_header.empty()) {
      result.push_back(cpp_header);
    }
    return result;
  }

  static string GetCppType(bool is_nullable,
                           const string& underlying_cpp_type) {
    if (is_nullable)
      return StringPrintf("::std::unique_ptr<::std::vector<%s>>",
                          underlying_cpp_type.c_str());
    return StringPrintf("::std::vector<%s>",
                        underlying_cpp_type.c_str());
  }

  DISALLOW_COPY_AND_ASSIGN(CppArrayType);
};  // class CppArrayType

class PrimitiveType : public Type {
 public:
  PrimitiveType(const std::string& aidl_type,
                const std::string& header,
                const std::string& cpp_type,
                const std::string& read_method,
                const std::string& write_method,
                const std::string& read_array_method,
                const std::string& write_array_method)
      : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, aidl_type, {header},
             cpp_type, read_method, write_method,
             new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
                              aidl_type, header, cpp_type,
                              read_array_method, write_array_method,
                              false)) {}

  virtual ~PrimitiveType() = default;
  bool IsCppPrimitive() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(PrimitiveType);
};  // class PrimitiveType

// Unfortunately, bytes in Java are signed.  However, most C authors would
// say that a byte is not in fact signed.  Compromise: customize this otherwise
// normal primitive to use signed single bytes, but unsigned byte arrays.
class ByteType : public Type {
 public:
  ByteType()
      : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "byte",
             {"cstdint"}, "int8_t", "readByte", "writeByte",
             new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
                              "byte", "cstdint", "uint8_t",
                              "readByteVector", "writeByteVector",
                              false)) {}

  virtual ~ByteType() = default;
  bool IsCppPrimitive() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(ByteType);
};  // class PrimitiveType

class BinderType : public Type {
 public:
  BinderType(const AidlInterface& interface, const std::string& src_file_name)
      : BinderType(interface, src_file_name,
                   new BinderType(interface, src_file_name, kNoNullableType,
                                  "readNullableStrongBinder"),
                   "readStrongBinder") {}
  virtual ~BinderType() = default;

  string WriteCast(const string& val) const override {
    return write_cast_ + "(" + val + ")";
  }

 private:
  BinderType(const AidlInterface& interface,
             const std::string& src_file_name,
             Type* nullable_type, const std::string& read)
      : Type(ValidatableType::KIND_GENERATED,
             interface.GetPackage(), interface.GetName(),
             {GetCppHeader(interface)}, GetCppName(interface),
             read, "writeStrongBinder", kNoArrayType, nullable_type,
             src_file_name, interface.GetLine()),
        write_cast_(GetRawCppName(interface) + "::asBinder") {}

  static string GetCppName(const AidlInterface& interface) {
    return "::android::sp<" + GetRawCppName(interface) + ">";
  }

  static string GetRawCppName(const AidlInterface& interface) {
    vector<string> name = interface.GetSplitPackage();
    string ret;

    name.push_back(interface.GetName());

    for (const auto& term : name) {
      ret += "::" + term;
    }

    return ret;
  }

  static string GetCppHeader(const AidlInterface& interface) {
    vector<string> name = interface.GetSplitPackage();
    name.push_back(interface.GetName());
    return Join(name, '/') + ".h";
  }

  std::string write_cast_;
};

class NullableParcelableType : public Type {
 public:
  NullableParcelableType(const AidlParcelable& parcelable,
                         const std::string& src_file_name)
      : Type(ValidatableType::KIND_PARCELABLE,
             parcelable.GetPackage(), parcelable.GetName(),
             {parcelable.GetCppHeader()}, GetCppName(parcelable),
             "readParcelable", "writeNullableParcelable",
             kNoArrayType, kNoNullableType,
             src_file_name, parcelable.GetLine()) {}
  virtual ~NullableParcelableType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  static string GetCppName(const AidlParcelable& parcelable) {
    return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
        "::" + parcelable.GetCppName() + ">";
  }
};

class ParcelableType : public Type {
 public:
  ParcelableType(const AidlParcelable& parcelable,
                 const std::string& src_file_name)
      : Type(ValidatableType::KIND_PARCELABLE,
             parcelable.GetPackage(), parcelable.GetName(),
             {parcelable.GetCppHeader()}, GetCppName(parcelable),
             "readParcelable", "writeParcelable",
             new CppArrayType(
                 ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(),
                 parcelable.GetName(), parcelable.GetCppHeader(),
                 GetCppName(parcelable),
                 "readParcelableVector", "writeParcelableVector", false,
                 src_file_name),
             new NullableParcelableType(parcelable, src_file_name),
             src_file_name, parcelable.GetLine()) {}
  virtual ~ParcelableType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  static string GetCppName(const AidlParcelable& parcelable) {
    return "::" + Join(parcelable.GetSplitPackage(), "::") +
        "::" + parcelable.GetCppName();
  }
};

class NullableStringListType : public Type {
 public:
  NullableStringListType()
      : Type(ValidatableType::KIND_BUILT_IN,
             "java.util", "List<" + string(kStringCanonicalName) + ">",
             {"utils/String16.h", "memory", "vector"},
             "::std::unique_ptr<::std::vector<std::unique_ptr<::android::String16>>>",
             "readString16Vector", "writeString16Vector") {}
  virtual ~NullableStringListType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(NullableStringListType);
};  // class NullableStringListType

class StringListType : public Type {
 public:
  StringListType()
      : Type(ValidatableType::KIND_BUILT_IN,
             "java.util", "List<" + string(kStringCanonicalName) + ">",
             {"utils/String16.h", "vector"},
             "::std::vector<::android::String16>",
             "readString16Vector", "writeString16Vector",
             kNoArrayType, new NullableStringListType()) {}
  virtual ~StringListType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(StringListType);
};  // class StringListType

class NullableUtf8InCppStringListType : public Type {
 public:
  NullableUtf8InCppStringListType()
      : Type(ValidatableType::KIND_BUILT_IN,
             "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
             {"memory", "string", "vector"},
             "::std::unique_ptr<::std::vector<std::unique_ptr<::std::string>>>",
             "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector") {}
  virtual ~NullableUtf8InCppStringListType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(NullableUtf8InCppStringListType);
};  // class NullableUtf8InCppStringListType

class Utf8InCppStringListType : public Type {
 public:
  Utf8InCppStringListType()
      : Type(ValidatableType::KIND_BUILT_IN,
             "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
             {"string", "vector"},
             "::std::vector<::std::string>",
             "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
             kNoArrayType, new NullableUtf8InCppStringListType()) {}
  virtual ~Utf8InCppStringListType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(Utf8InCppStringListType);
};  // class Utf8InCppStringListType

class NullableBinderListType : public Type {
 public:
  NullableBinderListType()
      : Type(ValidatableType::KIND_BUILT_IN, "java.util",
             "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
             "::std::unique_ptr<::std::vector<::android::sp<::android::IBinder>>>",
             "readStrongBinderVector", "writeStrongBinderVector") {}
  virtual ~NullableBinderListType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(NullableBinderListType);
};  // class NullableBinderListType

class BinderListType : public Type {
 public:
  BinderListType()
      : Type(ValidatableType::KIND_BUILT_IN, "java.util",
             "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
             "::std::vector<::android::sp<::android::IBinder>>",
             "readStrongBinderVector", "writeStrongBinderVector",
             kNoArrayType, new NullableBinderListType()) {}
  virtual ~BinderListType() = default;
  bool CanBeOutParameter() const override { return true; }

 private:
  DISALLOW_COPY_AND_ASSIGN(BinderListType);
};  // class BinderListType

}  // namespace

Type::Type(int kind,
           const std::string& package,
           const std::string& aidl_type,
           const vector<string>& headers,
           const string& cpp_type,
           const string& read_method,
           const string& write_method,
           Type* array_type,
           Type* nullable_type,
           const string& src_file_name,
           int line)
    : ValidatableType(kind, package, aidl_type, src_file_name, line),
      headers_(headers),
      aidl_type_(aidl_type),
      cpp_type_(cpp_type),
      parcel_read_method_(read_method),
      parcel_write_method_(write_method),
      array_type_(array_type),
      nullable_type_(nullable_type) {}

bool Type::CanWriteToParcel() const { return true; }

void TypeNamespace::Init() {
  Add(new ByteType());
  Add(new PrimitiveType(
      "int",
      "cstdint", "int32_t", "readInt32", "writeInt32",
      "readInt32Vector", "writeInt32Vector"));
  Add(new PrimitiveType(
      "long",
      "cstdint", "int64_t", "readInt64", "writeInt64",
      "readInt64Vector", "writeInt64Vector"));
  Add(new PrimitiveType(
      "float",
      kNoHeader, "float", "readFloat", "writeFloat",
      "readFloatVector", "writeFloatVector"));
  Add(new PrimitiveType(
      "double",
      kNoHeader, "double", "readDouble", "writeDouble",
      "readDoubleVector", "writeDoubleVector"));
  Add(new PrimitiveType(
      "boolean",
      kNoHeader, "bool", "readBool", "writeBool",
      "readBoolVector", "writeBoolVector"));
  // C++11 defines the char16_t type as a built in for Unicode characters.
  Add(new PrimitiveType(
      "char",
      kNoHeader, "char16_t", "readChar", "writeChar",
      "readCharVector", "writeCharVector"));

  Type* string_array_type = new CppArrayType(
      ValidatableType::KIND_BUILT_IN, "java.lang", "String",
      "utils/String16.h", "::android::String16",
      "readString16Vector", "writeString16Vector", false);

  Type* nullable_string_type =
      new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
               {"memory", "utils/String16.h"}, "::std::unique_ptr<::android::String16>",
               "readString16", "writeString16");

  string_type_ = new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
                          {"utils/String16.h"}, "::android::String16",
                          "readString16", "writeString16",
                          string_array_type, nullable_string_type);
  Add(string_type_);

  using ::android::aidl::kAidlReservedTypePackage;
  using ::android::aidl::kUtf8InCppStringClass;

  // This type is a Utf16 string in the parcel, but deserializes to
  // a std::string in Utf8 format when we use it in C++.
  Type* cpp_utf8_string_array = new CppArrayType(
      ValidatableType::KIND_BUILT_IN,
      kAidlReservedTypePackage, kUtf8InCppStringClass,
      "string", "::std::string",
      "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
      false);
  Type* nullable_cpp_utf8_string_type = new Type(
      ValidatableType::KIND_BUILT_IN,
      kAidlReservedTypePackage, kUtf8InCppStringClass,
      {"string", "memory"}, "::std::unique_ptr<::std::string>",
      "readUtf8FromUtf16", "writeUtf8AsUtf16");
  Add(new Type(
      ValidatableType::KIND_BUILT_IN,
      kAidlReservedTypePackage, kUtf8InCppStringClass,
      {"string"}, "::std::string", "readUtf8FromUtf16", "writeUtf8AsUtf16",
      cpp_utf8_string_array, nullable_cpp_utf8_string_type));

  Type* nullable_ibinder = new Type(
      ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
      {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
      "readNullableStrongBinder", "writeStrongBinder");
  ibinder_type_ = new Type(
      ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
      {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
      "readStrongBinder", "writeStrongBinder",
      kNoArrayType, nullable_ibinder);
  Add(ibinder_type_);

  Add(new BinderListType());
  Add(new StringListType());
  Add(new Utf8InCppStringListType());

  Type* fd_vector_type = new CppArrayType(
      ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
      "android-base/unique_fd.h",
      "::android::base::unique_fd",
      "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector",
      false);

  Add(new Type(
      ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
      {"android-base/unique_fd.h"}, "::android::base::unique_fd",
      "readUniqueFileDescriptor", "writeUniqueFileDescriptor",
      fd_vector_type));

  void_type_ = new class VoidType();
  Add(void_type_);
}

bool TypeNamespace::AddParcelableType(const AidlParcelable& p,
                                      const string& filename) {
  if (p.GetCppHeader().empty()) {
    LOG(ERROR) << "Parcelable " << p.GetCanonicalName()
               << " has no C++ header defined.";
    return false;
  }
  Add(new ParcelableType(p, filename));
  return true;
}

bool TypeNamespace::AddBinderType(const AidlInterface& b,
                                  const string& file_name) {
  Add(new BinderType(b, file_name));
  return true;
}

bool TypeNamespace::AddListType(const std::string& type_name) {
  const Type* contained_type = FindTypeByCanonicalName(type_name);
  if (!contained_type) {
    LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
                  "type cannot be found or is invalid.";
    return false;
  }
  if (contained_type->IsCppPrimitive()) {
    LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
                  "type is a primitive in Java and Java List cannot hold "
                  "primitives.";
    return false;
  }

  if (contained_type->CanonicalName() == kStringCanonicalName ||
      contained_type->CanonicalName() == kUtf8InCppStringCanonicalName ||
      contained_type == IBinderType()) {
    return true;
  }

  // TODO Support lists of parcelables b/23600712

  LOG(ERROR) << "aidl-cpp does not yet support List<" << type_name << ">";
  return false;
}

bool TypeNamespace::AddMapType(const std::string& /* key_type_name */,
                               const std::string& /* value_type_name */) {
  // TODO Support list types b/25242025
  LOG(ERROR) << "aidl does not implement support for typed maps!";
  return false;
}

bool TypeNamespace::IsValidPackage(const string& package) const {
  if (package.empty()) {
    return false;
  }

  auto pieces = Split(package, ".");
  for (const string& piece : pieces) {
    if (is_cpp_keyword(piece)) {
      return false;
    }
  }

  return true;
}

const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a,
    int arg_index,
    const std::string& filename,
    const AidlInterface& interface) const {
  const string error_prefix = StringPrintf(
      "In file %s line %d parameter %s (%d):\n    ",
      filename.c_str(), a.GetLine(), a.GetName().c_str(), arg_index);

  // check that the name doesn't match a keyword
  if (is_cpp_keyword(a.GetName().c_str())) {
    cerr << error_prefix << "Argument name is a C++ keyword"
         << endl;
    return nullptr;
  }

  return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, filename,
                                                    interface);
}

}  // namespace cpp
}  // namespace aidl
}  // namespace android
