// Copyright (C) 2019 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 "repr/protobuf/ir_dumper.h"

#include "repr/protobuf/abi_dump.h"
#include "repr/protobuf/api.h"

#include <fstream>
#include <memory>

#include <llvm/Support/raw_ostream.h>

#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/text_format.h>


namespace header_checker {
namespace repr {


bool IRToProtobufConverter::AddTemplateInformation(
    abi_dump::TemplateInfo *ti, const TemplatedArtifactIR *ta) {
  for (auto &&template_element : ta->GetTemplateElements()) {
    abi_dump::TemplateElement *added_element = ti->add_elements();
    if (!added_element) {
      llvm::errs() << "Failed to add template element\n";
      return false;
    }
    added_element->set_referenced_type(template_element.GetReferencedType());
  }
  return true;
}

bool IRToProtobufConverter::AddTypeInfo(
    abi_dump::BasicNamedAndTypedDecl *type_info, const TypeIR *typep) {
  if (!type_info || !typep) {
    llvm::errs() << "Typeinfo not valid\n";
    return false;
  }
  type_info->set_linker_set_key(typep->GetLinkerSetKey());
  type_info->set_source_file(typep->GetSourceFile());
  type_info->set_name(typep->GetName());
  type_info->set_size(typep->GetSize());
  type_info->set_alignment(typep->GetAlignment());
  type_info->set_referenced_type(typep->GetReferencedType());
  type_info->set_self_type(typep->GetSelfType());
  return true;
}

bool IRToProtobufConverter::AddRecordFields(
    abi_dump::RecordType *record_protobuf,
    const RecordTypeIR *record_ir) {
  // Iterate through the fields and create corresponding ones for the protobuf
  // record
  for (auto &&field_ir : record_ir->GetFields()) {
    abi_dump::RecordFieldDecl *added_field = record_protobuf->add_fields();
    if (!added_field) {
      llvm::errs() << "Couldn't add record field\n";
    }
    SetIRToProtobufRecordField(added_field, &field_ir);
  }
  return true;
}

bool IRToProtobufConverter::AddBaseSpecifiers(
    abi_dump::RecordType *record_protobuf, const RecordTypeIR *record_ir) {
  for (auto &&base_ir : record_ir->GetBases()) {
    abi_dump::CXXBaseSpecifier *added_base =
        record_protobuf->add_base_specifiers();
    if (!SetIRToProtobufBaseSpecifier(added_base, base_ir)) {
      return false;
    }
  }
  return true;
}

bool IRToProtobufConverter::AddVTableLayout(
    abi_dump::RecordType *record_protobuf,
    const RecordTypeIR *record_ir) {
  // If there are no entries in the vtable, just return.
  if (record_ir->GetVTableNumEntries() == 0) {
    return true;
  }
  const VTableLayoutIR &vtable_layout_ir = record_ir->GetVTableLayout();
  abi_dump::VTableLayout *vtable_layout_protobuf =
      record_protobuf->mutable_vtable_layout();
  if (!SetIRToProtobufVTableLayout(vtable_layout_protobuf, vtable_layout_ir)) {
    return false;
  }
  return true;
}

bool IRToProtobufConverter::AddTagTypeInfo(
    abi_dump::TagType *tag_type_protobuf,
    const TagTypeIR *tag_type_ir) {
  if (!tag_type_protobuf || !tag_type_ir) {
    return false;
  }
  tag_type_protobuf->set_unique_id(tag_type_ir->GetUniqueId());
  return true;
}

abi_dump::RecordType IRToProtobufConverter::ConvertRecordTypeIR(
    const RecordTypeIR *recordp) {
  abi_dump::RecordType added_record_type;
  added_record_type.set_access(AccessIRToProtobuf(recordp->GetAccess()));
  added_record_type.set_record_kind(
      RecordKindIRToProtobuf(recordp->GetRecordKind()));
  if (recordp->IsAnonymous()) {
    added_record_type.set_is_anonymous(true);
  }
  if (!AddTypeInfo(added_record_type.mutable_type_info(), recordp) ||
      !AddRecordFields(&added_record_type, recordp) ||
      !AddBaseSpecifiers(&added_record_type, recordp) ||
      !AddVTableLayout(&added_record_type, recordp) ||
      !AddTagTypeInfo(added_record_type.mutable_tag_info(), recordp) ||
      !(recordp->GetTemplateElements().size() ?
        AddTemplateInformation(added_record_type.mutable_template_info(),
                               recordp) : true)) {
    llvm::errs() << "Template information could not be added\n";
    ::exit(1);
  }
  return added_record_type;
}


abi_dump::ElfObject IRToProtobufConverter::ConvertElfObjectIR(
    const ElfObjectIR *elf_object_ir) {
  abi_dump::ElfObject elf_object_protobuf;
  elf_object_protobuf.set_name(elf_object_ir->GetName());
  return elf_object_protobuf;
}

abi_dump::ElfFunction IRToProtobufConverter::ConvertElfFunctionIR(
    const ElfFunctionIR *elf_function_ir) {
  abi_dump::ElfFunction elf_function_protobuf;
  elf_function_protobuf.set_name(elf_function_ir->GetName());
  return elf_function_protobuf;
}

template <typename CFunctionLikeMessage>
bool IRToProtobufConverter::AddFunctionParametersAndSetReturnType(
    CFunctionLikeMessage *function_like_protobuf,
    const CFunctionLikeIR *cfunction_like_ir) {
  function_like_protobuf->set_return_type(cfunction_like_ir->GetReturnType());
  return AddFunctionParameters(function_like_protobuf, cfunction_like_ir);
}

template <typename CFunctionLikeMessage>
bool IRToProtobufConverter::AddFunctionParameters(
    CFunctionLikeMessage *function_like_protobuf,
    const CFunctionLikeIR *cfunction_like_ir) {
  for (auto &&parameter : cfunction_like_ir->GetParameters()) {
    abi_dump::ParamDecl *added_parameter =
        function_like_protobuf->add_parameters();
    if (!added_parameter) {
      return false;
    }
    added_parameter->set_referenced_type(
        parameter.GetReferencedType());
    added_parameter->set_default_arg(parameter.GetIsDefault());
    added_parameter->set_is_this_ptr(parameter.GetIsThisPtr());
  }
  return true;
}

abi_dump::FunctionType IRToProtobufConverter::ConvertFunctionTypeIR (
    const FunctionTypeIR *function_typep) {
  abi_dump::FunctionType added_function_type;
  if (!AddTypeInfo(added_function_type.mutable_type_info(), function_typep) ||
      !AddFunctionParametersAndSetReturnType(&added_function_type,
                                             function_typep)) {
    llvm::errs() << "Could not convert FunctionTypeIR to protobuf\n";
    ::exit(1);
  }
  return added_function_type;
}

abi_dump::FunctionDecl IRToProtobufConverter::ConvertFunctionIR(
    const FunctionIR *functionp) {
  abi_dump::FunctionDecl added_function;
  added_function.set_access(AccessIRToProtobuf(functionp->GetAccess()));
  added_function.set_linker_set_key(functionp->GetLinkerSetKey());
  added_function.set_source_file(functionp->GetSourceFile());
  added_function.set_function_name(functionp->GetName());
  if (!AddFunctionParametersAndSetReturnType(&added_function, functionp) ||
      !(functionp->GetTemplateElements().size() ?
      AddTemplateInformation(added_function.mutable_template_info(), functionp)
      : true)) {
    llvm::errs() << "Template information could not be added\n";
    ::exit(1);
  }
  return added_function;
}

bool IRToProtobufConverter::AddEnumFields(abi_dump::EnumType *enum_protobuf,
                                          const EnumTypeIR *enum_ir) {
  for (auto &&field : enum_ir->GetFields()) {
    abi_dump::EnumFieldDecl *enum_fieldp = enum_protobuf->add_enum_fields();
    if (!SetIRToProtobufEnumField(enum_fieldp, &field)) {
      return false;
    }
  }
  return true;
}


abi_dump::EnumType IRToProtobufConverter::ConvertEnumTypeIR(
    const EnumTypeIR *enump) {
  abi_dump::EnumType added_enum_type;
  added_enum_type.set_access(AccessIRToProtobuf(enump->GetAccess()));
  added_enum_type.set_underlying_type(enump->GetUnderlyingType());
  if (!AddTypeInfo(added_enum_type.mutable_type_info(), enump) ||
      !AddEnumFields(&added_enum_type, enump) ||
      !AddTagTypeInfo(added_enum_type.mutable_tag_info(), enump)) {
    llvm::errs() << "EnumTypeIR could not be converted\n";
    ::exit(1);
  }
  return added_enum_type;
}

abi_dump::GlobalVarDecl IRToProtobufConverter::ConvertGlobalVarIR(
    const GlobalVarIR *global_varp) {
  abi_dump::GlobalVarDecl added_global_var;
  added_global_var.set_referenced_type(global_varp->GetReferencedType());
  added_global_var.set_source_file(global_varp->GetSourceFile());
  added_global_var.set_name(global_varp->GetName());
  added_global_var.set_linker_set_key(global_varp->GetLinkerSetKey());
  added_global_var.set_access(
      AccessIRToProtobuf(global_varp->GetAccess()));
  return added_global_var;
}

abi_dump::PointerType IRToProtobufConverter::ConvertPointerTypeIR(
    const PointerTypeIR *pointerp) {
  abi_dump::PointerType added_pointer_type;
  if (!AddTypeInfo(added_pointer_type.mutable_type_info(), pointerp)) {
    llvm::errs() << "PointerTypeIR could not be converted\n";
    ::exit(1);
  }
  return added_pointer_type;
}

abi_dump::QualifiedType IRToProtobufConverter::ConvertQualifiedTypeIR(
    const QualifiedTypeIR *qualtypep) {
  abi_dump::QualifiedType added_qualified_type;
  if (!AddTypeInfo(added_qualified_type.mutable_type_info(), qualtypep)) {
    llvm::errs() << "QualifiedTypeIR could not be converted\n";
    ::exit(1);
  }
  added_qualified_type.set_is_const(qualtypep->IsConst());
  added_qualified_type.set_is_volatile(qualtypep->IsVolatile());
  added_qualified_type.set_is_restricted(qualtypep->IsRestricted());
  return added_qualified_type;
}

abi_dump::BuiltinType IRToProtobufConverter::ConvertBuiltinTypeIR(
    const BuiltinTypeIR *builtin_typep) {
  abi_dump::BuiltinType added_builtin_type;
  added_builtin_type.set_is_unsigned(builtin_typep->IsUnsigned());
  added_builtin_type.set_is_integral(builtin_typep->IsIntegralType());
  if (!AddTypeInfo(added_builtin_type.mutable_type_info(), builtin_typep)) {
    llvm::errs() << "BuiltinTypeIR could not be converted\n";
    ::exit(1);
  }
  return added_builtin_type;
}

abi_dump::ArrayType IRToProtobufConverter::ConvertArrayTypeIR(
    const ArrayTypeIR *array_typep) {
  abi_dump::ArrayType added_array_type;
  if (!AddTypeInfo(added_array_type.mutable_type_info(), array_typep)) {
    llvm::errs() << "ArrayTypeIR could not be converted\n";
    ::exit(1);
  }
  return added_array_type;
}

abi_dump::LvalueReferenceType
IRToProtobufConverter::ConvertLvalueReferenceTypeIR(
    const LvalueReferenceTypeIR *lvalue_reference_typep) {
  abi_dump::LvalueReferenceType added_lvalue_reference_type;
  if (!AddTypeInfo(added_lvalue_reference_type.mutable_type_info(),
                   lvalue_reference_typep)) {
    llvm::errs() << "LvalueReferenceTypeIR could not be converted\n";
    ::exit(1);
  }
  return added_lvalue_reference_type;
}

abi_dump::RvalueReferenceType
IRToProtobufConverter::ConvertRvalueReferenceTypeIR(
    const RvalueReferenceTypeIR *rvalue_reference_typep) {
  abi_dump::RvalueReferenceType added_rvalue_reference_type;
  if (!AddTypeInfo(added_rvalue_reference_type.mutable_type_info(),
                   rvalue_reference_typep)) {
    llvm::errs() << "RvalueReferenceTypeIR could not be converted\n";
    ::exit(1);
  }
  return added_rvalue_reference_type;
}

bool ProtobufIRDumper::AddLinkableMessageIR (const LinkableMessageIR *lm) {
  // No RTTI
  switch (lm->GetKind()) {
    case RecordTypeKind:
      return AddRecordTypeIR(static_cast<const RecordTypeIR *>(lm));
    case EnumTypeKind:
      return AddEnumTypeIR(static_cast<const EnumTypeIR *>(lm));
    case PointerTypeKind:
      return AddPointerTypeIR(static_cast<const PointerTypeIR *>(lm));
    case QualifiedTypeKind:
      return AddQualifiedTypeIR(static_cast<const QualifiedTypeIR *>(lm));
    case ArrayTypeKind:
      return AddArrayTypeIR(static_cast<const ArrayTypeIR *>(lm));
    case LvalueReferenceTypeKind:
      return AddLvalueReferenceTypeIR(
          static_cast<const LvalueReferenceTypeIR *>(lm));
    case RvalueReferenceTypeKind:
      return AddRvalueReferenceTypeIR(
          static_cast<const RvalueReferenceTypeIR*>(lm));
    case BuiltinTypeKind:
      return AddBuiltinTypeIR(static_cast<const BuiltinTypeIR*>(lm));
    case FunctionTypeKind:
      return AddFunctionTypeIR(static_cast<const FunctionTypeIR*>(lm));
    case GlobalVarKind:
      return AddGlobalVarIR(static_cast<const GlobalVarIR*>(lm));
    case FunctionKind:
      return AddFunctionIR(static_cast<const FunctionIR*>(lm));
  }
  return false;
}

bool ProtobufIRDumper::AddElfFunctionIR(const ElfFunctionIR *elf_function) {
  abi_dump::ElfFunction *added_elf_function = tu_ptr_->add_elf_functions();
  if (!added_elf_function) {
    return false;
  }
  added_elf_function->set_name(elf_function->GetName());
  added_elf_function->set_binding(
      ElfSymbolBindingIRToProtobuf(elf_function->GetBinding()));
  return true;
}

bool ProtobufIRDumper::AddElfObjectIR(const ElfObjectIR *elf_object) {
  abi_dump::ElfObject *added_elf_object = tu_ptr_->add_elf_objects();
  if (!added_elf_object) {
    return false;
  }
  added_elf_object->set_name(elf_object->GetName());
  added_elf_object->set_binding(
      ElfSymbolBindingIRToProtobuf(elf_object->GetBinding()));
  return true;
}

bool ProtobufIRDumper::AddElfSymbolMessageIR(const ElfSymbolIR *em) {
  switch (em->GetKind()) {
    case ElfSymbolIR::ElfFunctionKind:
      return AddElfFunctionIR(static_cast<const ElfFunctionIR *>(em));
    case ElfSymbolIR::ElfObjectKind:
      return AddElfObjectIR(static_cast<const ElfObjectIR *>(em));
  }
  return false;
}

bool ProtobufIRDumper::AddRecordTypeIR(const RecordTypeIR *recordp) {
  abi_dump::RecordType *added_record_type = tu_ptr_->add_record_types();
  if (!added_record_type) {
    return false;
  }
  *added_record_type = ConvertRecordTypeIR(recordp);
  return true;
}

bool ProtobufIRDumper::AddFunctionTypeIR(const FunctionTypeIR *function_typep) {
  abi_dump::FunctionType *added_function_type = tu_ptr_->add_function_types();
  if (!added_function_type) {
    return false;
  }
  *added_function_type = ConvertFunctionTypeIR(function_typep);
  return true;
}

bool ProtobufIRDumper::AddFunctionIR(const FunctionIR *functionp) {
  abi_dump::FunctionDecl *added_function = tu_ptr_->add_functions();
  if (!added_function) {
    return false;
  }
  *added_function = ConvertFunctionIR(functionp);
  return true;
}

bool ProtobufIRDumper::AddEnumTypeIR(const EnumTypeIR *enump) {
  abi_dump::EnumType *added_enum_type = tu_ptr_->add_enum_types();
  if (!added_enum_type) {
    return false;
  }
  *added_enum_type = ConvertEnumTypeIR(enump);
  return true;
}

bool ProtobufIRDumper::AddGlobalVarIR(const GlobalVarIR *global_varp) {
  abi_dump::GlobalVarDecl *added_global_var = tu_ptr_->add_global_vars();
  if (!added_global_var) {
    return false;
  }
  *added_global_var = ConvertGlobalVarIR(global_varp);
  return true;
}

bool ProtobufIRDumper::AddPointerTypeIR(const PointerTypeIR *pointerp) {
  abi_dump::PointerType *added_pointer_type = tu_ptr_->add_pointer_types();
  if (!added_pointer_type) {
    return false;
  }
  *added_pointer_type = ConvertPointerTypeIR(pointerp);
  return true;
}

bool ProtobufIRDumper::AddQualifiedTypeIR(const QualifiedTypeIR *qualtypep) {
  abi_dump::QualifiedType *added_qualified_type =
      tu_ptr_->add_qualified_types();
  if (!added_qualified_type) {
    return false;
  }
  *added_qualified_type = ConvertQualifiedTypeIR(qualtypep);
  return true;
}

bool ProtobufIRDumper::AddBuiltinTypeIR(const BuiltinTypeIR *builtin_typep) {
  abi_dump::BuiltinType *added_builtin_type =
      tu_ptr_->add_builtin_types();
  if (!added_builtin_type) {
    return false;
  }
  *added_builtin_type = ConvertBuiltinTypeIR(builtin_typep);
  return true;
}

bool ProtobufIRDumper::AddArrayTypeIR(const ArrayTypeIR *array_typep) {
  abi_dump::ArrayType *added_array_type =
      tu_ptr_->add_array_types();
  if (!added_array_type) {
    return false;
  }
  *added_array_type = ConvertArrayTypeIR(array_typep);
  return true;
}

bool ProtobufIRDumper::AddLvalueReferenceTypeIR(
    const LvalueReferenceTypeIR *lvalue_reference_typep) {
  abi_dump::LvalueReferenceType *added_lvalue_reference_type =
      tu_ptr_->add_lvalue_reference_types();
  if (!added_lvalue_reference_type) {
    return false;
  }
  *added_lvalue_reference_type =
      ConvertLvalueReferenceTypeIR(lvalue_reference_typep);
  return true;
}

bool ProtobufIRDumper::AddRvalueReferenceTypeIR(
    const RvalueReferenceTypeIR *rvalue_reference_typep) {
  abi_dump::RvalueReferenceType *added_rvalue_reference_type =
      tu_ptr_->add_rvalue_reference_types();
  if (!added_rvalue_reference_type) {
    return false;
  }
  *added_rvalue_reference_type =
      ConvertRvalueReferenceTypeIR(rvalue_reference_typep);
  return true;
}

bool ProtobufIRDumper::Dump(const ModuleIR &module) {
  GOOGLE_PROTOBUF_VERIFY_VERSION;
  DumpModule(module);
  assert( tu_ptr_.get() != nullptr);
  std::ofstream text_output(dump_path_);
  google::protobuf::io::OstreamOutputStream text_os(&text_output);
  return google::protobuf::TextFormat::Print(*tu_ptr_.get(), &text_os);
}

std::unique_ptr<IRDumper> CreateProtobufIRDumper(const std::string &dump_path) {
  return std::make_unique<ProtobufIRDumper>(dump_path);
}


}  // namespace repr
}  // namespace header_checker
