/*
 * Copyright (C) 2016 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.
 *
 * Header file of an in-memory representation of DEX files.
 */

#include <stdint.h>

#include <queue>
#include <vector>

#include "dex_writer.h"
#include "utf.h"

namespace art {

size_t EncodeIntValue(int32_t value, uint8_t* buffer) {
  size_t length = 0;
  if (value >= 0) {
    while (value > 0x7f) {
      buffer[length++] = static_cast<uint8_t>(value);
      value >>= 8;
    }
  } else {
    while (value < -0x80) {
      buffer[length++] = static_cast<uint8_t>(value);
      value >>= 8;
    }
  }
  buffer[length++] = static_cast<uint8_t>(value);
  return length;
}

size_t EncodeUIntValue(uint32_t value, uint8_t* buffer) {
  size_t length = 0;
  do {
    buffer[length++] = static_cast<uint8_t>(value);
    value >>= 8;
  } while (value != 0);
  return length;
}

size_t EncodeLongValue(int64_t value, uint8_t* buffer) {
  size_t length = 0;
  if (value >= 0) {
    while (value > 0x7f) {
      buffer[length++] = static_cast<uint8_t>(value);
      value >>= 8;
    }
  } else {
    while (value < -0x80) {
      buffer[length++] = static_cast<uint8_t>(value);
      value >>= 8;
    }
  }
  buffer[length++] = static_cast<uint8_t>(value);
  return length;
}

union FloatUnion {
  float f_;
  uint32_t i_;
};

size_t EncodeFloatValue(float value, uint8_t* buffer) {
  FloatUnion float_union;
  float_union.f_ = value;
  uint32_t int_value = float_union.i_;
  size_t index = 3;
  do {
    buffer[index--] = int_value >> 24;
    int_value <<= 8;
  } while (int_value != 0);
  return 3 - index;
}

union DoubleUnion {
  double d_;
  uint64_t l_;
};

size_t EncodeDoubleValue(double value, uint8_t* buffer) {
  DoubleUnion double_union;
  double_union.d_ = value;
  uint64_t long_value = double_union.l_;
  size_t index = 7;
  do {
    buffer[index--] = long_value >> 56;
    long_value <<= 8;
  } while (long_value != 0);
  return 7 - index;
}

size_t DexWriter::Write(const void* buffer, size_t length, size_t offset) {
  return dex_file_->PwriteFully(buffer, length, offset) ? length : 0;
}

size_t DexWriter::WriteSleb128(uint32_t value, size_t offset) {
  uint8_t buffer[8];
  EncodeSignedLeb128(buffer, value);
  return Write(buffer, SignedLeb128Size(value), offset);
}

size_t DexWriter::WriteUleb128(uint32_t value, size_t offset) {
  uint8_t buffer[8];
  EncodeUnsignedLeb128(buffer, value);
  return Write(buffer, UnsignedLeb128Size(value), offset);
}

size_t DexWriter::WriteEncodedValue(dex_ir::EncodedValue* encoded_value, size_t offset) {
  size_t original_offset = offset;
  size_t start = 0;
  size_t length;
  uint8_t buffer[8];
  int8_t type = encoded_value->Type();
  switch (type) {
    case DexFile::kDexAnnotationByte:
      length = EncodeIntValue(encoded_value->GetByte(), buffer);
      break;
    case DexFile::kDexAnnotationShort:
      length = EncodeIntValue(encoded_value->GetShort(), buffer);
      break;
    case DexFile::kDexAnnotationChar:
      length = EncodeUIntValue(encoded_value->GetChar(), buffer);
      break;
    case DexFile::kDexAnnotationInt:
      length = EncodeIntValue(encoded_value->GetInt(), buffer);
      break;
    case DexFile::kDexAnnotationLong:
      length = EncodeLongValue(encoded_value->GetLong(), buffer);
      break;
    case DexFile::kDexAnnotationFloat:
      length = EncodeFloatValue(encoded_value->GetFloat(), buffer);
      start = 4 - length;
      break;
    case DexFile::kDexAnnotationDouble:
      length = EncodeDoubleValue(encoded_value->GetDouble(), buffer);
      start = 8 - length;
      break;
    case DexFile::kDexAnnotationString:
      length = EncodeUIntValue(encoded_value->GetStringId()->GetIndex(), buffer);
      break;
    case DexFile::kDexAnnotationType:
      length = EncodeUIntValue(encoded_value->GetTypeId()->GetIndex(), buffer);
      break;
    case DexFile::kDexAnnotationField:
    case DexFile::kDexAnnotationEnum:
      length = EncodeUIntValue(encoded_value->GetFieldId()->GetIndex(), buffer);
      break;
    case DexFile::kDexAnnotationMethod:
      length = EncodeUIntValue(encoded_value->GetMethodId()->GetIndex(), buffer);
      break;
    case DexFile::kDexAnnotationArray:
      offset += WriteEncodedValueHeader(type, 0, offset);
      offset += WriteEncodedArray(encoded_value->GetEncodedArray()->GetEncodedValues(), offset);
      return offset - original_offset;
    case DexFile::kDexAnnotationAnnotation:
      offset += WriteEncodedValueHeader(type, 0, offset);
      offset += WriteEncodedAnnotation(encoded_value->GetEncodedAnnotation(), offset);
      return offset - original_offset;
    case DexFile::kDexAnnotationNull:
      return WriteEncodedValueHeader(type, 0, offset);
    case DexFile::kDexAnnotationBoolean:
      return WriteEncodedValueHeader(type, encoded_value->GetBoolean() ? 1 : 0, offset);
    default:
      return 0;
  }
  offset += WriteEncodedValueHeader(type, length - 1, offset);
  offset += Write(buffer + start, length, offset);
  return offset - original_offset;
}

size_t DexWriter::WriteEncodedValueHeader(int8_t value_type, size_t value_arg, size_t offset) {
  uint8_t buffer[1] = { static_cast<uint8_t>((value_arg << 5) | value_type) };
  return Write(buffer, sizeof(uint8_t), offset);
}

size_t DexWriter::WriteEncodedArray(dex_ir::EncodedValueVector* values, size_t offset) {
  size_t original_offset = offset;
  offset += WriteUleb128(values->size(), offset);
  for (std::unique_ptr<dex_ir::EncodedValue>& value : *values) {
    offset += WriteEncodedValue(value.get(), offset);
  }
  return offset - original_offset;
}

size_t DexWriter::WriteEncodedAnnotation(dex_ir::EncodedAnnotation* annotation, size_t offset) {
  size_t original_offset = offset;
  offset += WriteUleb128(annotation->GetType()->GetIndex(), offset);
  offset += WriteUleb128(annotation->GetAnnotationElements()->size(), offset);
  for (std::unique_ptr<dex_ir::AnnotationElement>& annotation_element :
      *annotation->GetAnnotationElements()) {
    offset += WriteUleb128(annotation_element->GetName()->GetIndex(), offset);
    offset += WriteEncodedValue(annotation_element->GetValue(), offset);
  }
  return offset - original_offset;
}

size_t DexWriter::WriteEncodedFields(dex_ir::FieldItemVector* fields, size_t offset) {
  size_t original_offset = offset;
  uint32_t prev_index = 0;
  for (std::unique_ptr<dex_ir::FieldItem>& field : *fields) {
    uint32_t index = field->GetFieldId()->GetIndex();
    offset += WriteUleb128(index - prev_index, offset);
    offset += WriteUleb128(field->GetAccessFlags(), offset);
    prev_index = index;
  }
  return offset - original_offset;
}

size_t DexWriter::WriteEncodedMethods(dex_ir::MethodItemVector* methods, size_t offset) {
  size_t original_offset = offset;
  uint32_t prev_index = 0;
  for (std::unique_ptr<dex_ir::MethodItem>& method : *methods) {
    uint32_t index = method->GetMethodId()->GetIndex();
    uint32_t code_off = method->GetCodeItem() == nullptr ? 0 : method->GetCodeItem()->GetOffset();
    offset += WriteUleb128(index - prev_index, offset);
    offset += WriteUleb128(method->GetAccessFlags(), offset);
    offset += WriteUleb128(code_off, offset);
    prev_index = index;
  }
  return offset - original_offset;
}

void DexWriter::WriteStrings() {
  uint32_t string_data_off[1];
  for (std::unique_ptr<dex_ir::StringId>& string_id : header_.GetCollections().StringIds()) {
    string_data_off[0] = string_id->DataItem()->GetOffset();
    Write(string_data_off, string_id->GetSize(), string_id->GetOffset());
  }

  for (std::unique_ptr<dex_ir::StringData>& string_data : header_.GetCollections().StringDatas()) {
    uint32_t offset = string_data->GetOffset();
    offset += WriteUleb128(CountModifiedUtf8Chars(string_data->Data()), offset);
    Write(string_data->Data(), strlen(string_data->Data()), offset);
  }
}

void DexWriter::WriteTypes() {
  uint32_t descriptor_idx[1];
  for (std::unique_ptr<dex_ir::TypeId>& type_id : header_.GetCollections().TypeIds()) {
    descriptor_idx[0] = type_id->GetStringId()->GetIndex();
    Write(descriptor_idx, type_id->GetSize(), type_id->GetOffset());
  }
}

void DexWriter::WriteTypeLists() {
  uint32_t size[1];
  uint16_t list[1];
  for (std::unique_ptr<dex_ir::TypeList>& type_list : header_.GetCollections().TypeLists()) {
    size[0] = type_list->GetTypeList()->size();
    uint32_t offset = type_list->GetOffset();
    offset += Write(size, sizeof(uint32_t), offset);
    for (const dex_ir::TypeId* type_id : *type_list->GetTypeList()) {
      list[0] = type_id->GetIndex();
      offset += Write(list, sizeof(uint16_t), offset);
    }
  }
}

void DexWriter::WriteProtos() {
  uint32_t buffer[3];
  for (std::unique_ptr<dex_ir::ProtoId>& proto_id : header_.GetCollections().ProtoIds()) {
    buffer[0] = proto_id->Shorty()->GetIndex();
    buffer[1] = proto_id->ReturnType()->GetIndex();
    buffer[2] = proto_id->Parameters() == nullptr ? 0 : proto_id->Parameters()->GetOffset();
    Write(buffer, proto_id->GetSize(), proto_id->GetOffset());
  }
}

void DexWriter::WriteFields() {
  uint16_t buffer[4];
  for (std::unique_ptr<dex_ir::FieldId>& field_id : header_.GetCollections().FieldIds()) {
    buffer[0] = field_id->Class()->GetIndex();
    buffer[1] = field_id->Type()->GetIndex();
    buffer[2] = field_id->Name()->GetIndex();
    buffer[3] = field_id->Name()->GetIndex() >> 16;
    Write(buffer, field_id->GetSize(), field_id->GetOffset());
  }
}

void DexWriter::WriteMethods() {
  uint16_t buffer[4];
  for (std::unique_ptr<dex_ir::MethodId>& method_id : header_.GetCollections().MethodIds()) {
    buffer[0] = method_id->Class()->GetIndex();
    buffer[1] = method_id->Proto()->GetIndex();
    buffer[2] = method_id->Name()->GetIndex();
    buffer[3] = method_id->Name()->GetIndex() >> 16;
    Write(buffer, method_id->GetSize(), method_id->GetOffset());
  }
}

void DexWriter::WriteEncodedArrays() {
  for (std::unique_ptr<dex_ir::EncodedArrayItem>& encoded_array :
      header_.GetCollections().EncodedArrayItems()) {
    WriteEncodedArray(encoded_array->GetEncodedValues(), encoded_array->GetOffset());
  }
}

void DexWriter::WriteAnnotations() {
  uint8_t visibility[1];
  for (std::unique_ptr<dex_ir::AnnotationItem>& annotation :
      header_.GetCollections().AnnotationItems()) {
    visibility[0] = annotation->GetVisibility();
    size_t offset = annotation->GetOffset();
    offset += Write(visibility, sizeof(uint8_t), offset);
    WriteEncodedAnnotation(annotation->GetAnnotation(), offset);
  }
}

void DexWriter::WriteAnnotationSets() {
  uint32_t size[1];
  uint32_t annotation_off[1];
  for (std::unique_ptr<dex_ir::AnnotationSetItem>& annotation_set :
      header_.GetCollections().AnnotationSetItems()) {
    size[0] = annotation_set->GetItems()->size();
    size_t offset = annotation_set->GetOffset();
    offset += Write(size, sizeof(uint32_t), offset);
    for (dex_ir::AnnotationItem* annotation : *annotation_set->GetItems()) {
      annotation_off[0] = annotation->GetOffset();
      offset += Write(annotation_off, sizeof(uint32_t), offset);
    }
  }
}

void DexWriter::WriteAnnotationSetRefs() {
  uint32_t size[1];
  uint32_t annotations_off[1];
  for (std::unique_ptr<dex_ir::AnnotationSetRefList>& annotation_set_ref :
        header_.GetCollections().AnnotationSetRefLists()) {
    size[0] = annotation_set_ref->GetItems()->size();
    size_t offset = annotation_set_ref->GetOffset();
    offset += Write(size, sizeof(uint32_t), offset);
    for (dex_ir::AnnotationSetItem* annotation_set : *annotation_set_ref->GetItems()) {
      annotations_off[0] = annotation_set == nullptr ? 0 : annotation_set->GetOffset();
      offset += Write(annotations_off, sizeof(uint32_t), offset);
    }
  }
}

void DexWriter::WriteAnnotationsDirectories() {
  uint32_t directory_buffer[4];
  uint32_t annotation_buffer[2];
  for (std::unique_ptr<dex_ir::AnnotationsDirectoryItem>& annotations_directory :
          header_.GetCollections().AnnotationsDirectoryItems()) {
    directory_buffer[0] = annotations_directory->GetClassAnnotation() == nullptr ? 0 :
        annotations_directory->GetClassAnnotation()->GetOffset();
    directory_buffer[1] = annotations_directory->GetFieldAnnotations() == nullptr ? 0 :
        annotations_directory->GetFieldAnnotations()->size();
    directory_buffer[2] = annotations_directory->GetMethodAnnotations() == nullptr ? 0 :
        annotations_directory->GetMethodAnnotations()->size();
    directory_buffer[3] = annotations_directory->GetParameterAnnotations() == nullptr ? 0 :
        annotations_directory->GetParameterAnnotations()->size();
    uint32_t offset = annotations_directory->GetOffset();
    offset += Write(directory_buffer, 4 * sizeof(uint32_t), offset);
    if (annotations_directory->GetFieldAnnotations() != nullptr) {
      for (std::unique_ptr<dex_ir::FieldAnnotation>& field :
          *annotations_directory->GetFieldAnnotations()) {
        annotation_buffer[0] = field->GetFieldId()->GetIndex();
        annotation_buffer[1] = field->GetAnnotationSetItem()->GetOffset();
        offset += Write(annotation_buffer, 2 * sizeof(uint32_t), offset);
      }
    }
    if (annotations_directory->GetMethodAnnotations() != nullptr) {
      for (std::unique_ptr<dex_ir::MethodAnnotation>& method :
          *annotations_directory->GetMethodAnnotations()) {
        annotation_buffer[0] = method->GetMethodId()->GetIndex();
        annotation_buffer[1] = method->GetAnnotationSetItem()->GetOffset();
        offset += Write(annotation_buffer, 2 * sizeof(uint32_t), offset);
      }
    }
    if (annotations_directory->GetParameterAnnotations() != nullptr) {
      for (std::unique_ptr<dex_ir::ParameterAnnotation>& parameter :
          *annotations_directory->GetParameterAnnotations()) {
        annotation_buffer[0] = parameter->GetMethodId()->GetIndex();
        annotation_buffer[1] = parameter->GetAnnotations()->GetOffset();
        offset += Write(annotation_buffer, 2 * sizeof(uint32_t), offset);
      }
    }
  }
}

void DexWriter::WriteDebugInfoItems() {
  for (std::unique_ptr<dex_ir::DebugInfoItem>& info : header_.GetCollections().DebugInfoItems()) {
    Write(info->GetDebugInfo(), info->GetDebugInfoSize(), info->GetOffset());
  }
}

void DexWriter::WriteCodeItems() {
  uint16_t uint16_buffer[4];
  uint32_t uint32_buffer[2];
  for (std::unique_ptr<dex_ir::CodeItem>& code_item : header_.GetCollections().CodeItems()) {
    uint16_buffer[0] = code_item->RegistersSize();
    uint16_buffer[1] = code_item->InsSize();
    uint16_buffer[2] = code_item->OutsSize();
    uint16_buffer[3] = code_item->TriesSize();
    uint32_buffer[0] = code_item->DebugInfo() == nullptr ? 0 : code_item->DebugInfo()->GetOffset();
    uint32_buffer[1] = code_item->InsnsSize();
    size_t offset = code_item->GetOffset();
    offset += Write(uint16_buffer, 4 * sizeof(uint16_t), offset);
    offset += Write(uint32_buffer, 2 * sizeof(uint32_t), offset);
    offset += Write(code_item->Insns(), code_item->InsnsSize() * sizeof(uint16_t), offset);
    if (code_item->TriesSize() != 0) {
      if (code_item->InsnsSize() % 2 != 0) {
        uint16_t padding[1] = { 0 };
        offset += Write(padding, sizeof(uint16_t), offset);
      }
      uint32_t start_addr[1];
      uint16_t insn_count_and_handler_off[2];
      for (std::unique_ptr<const dex_ir::TryItem>& try_item : *code_item->Tries()) {
        start_addr[0] = try_item->StartAddr();
        insn_count_and_handler_off[0] = try_item->InsnCount();
        insn_count_and_handler_off[1] = try_item->GetHandlers()->GetListOffset();
        offset += Write(start_addr, sizeof(uint32_t), offset);
        offset += Write(insn_count_and_handler_off, 2 * sizeof(uint16_t), offset);
      }
      // Leave offset pointing to the end of the try items.
      WriteUleb128(code_item->Handlers()->size(), offset);
      for (std::unique_ptr<const dex_ir::CatchHandler>& handlers : *code_item->Handlers()) {
        size_t list_offset = offset + handlers->GetListOffset();
        uint32_t size = handlers->HasCatchAll() ? (handlers->GetHandlers()->size() - 1) * -1 :
            handlers->GetHandlers()->size();
        list_offset += WriteSleb128(size, list_offset);
        for (std::unique_ptr<const dex_ir::TypeAddrPair>& handler : *handlers->GetHandlers()) {
          if (handler->GetTypeId() != nullptr) {
            list_offset += WriteUleb128(handler->GetTypeId()->GetIndex(), list_offset);
          }
          list_offset += WriteUleb128(handler->GetAddress(), list_offset);
        }
      }
    }
  }
}

void DexWriter::WriteClasses() {
  uint32_t class_def_buffer[8];
  for (std::unique_ptr<dex_ir::ClassDef>& class_def : header_.GetCollections().ClassDefs()) {
    class_def_buffer[0] = class_def->ClassType()->GetIndex();
    class_def_buffer[1] = class_def->GetAccessFlags();
    class_def_buffer[2] = class_def->Superclass() == nullptr ? DexFile::kDexNoIndex :
        class_def->Superclass()->GetIndex();
    class_def_buffer[3] = class_def->InterfacesOffset();
    class_def_buffer[4] = class_def->SourceFile() == nullptr ? DexFile::kDexNoIndex :
        class_def->SourceFile()->GetIndex();
    class_def_buffer[5] = class_def->Annotations() == nullptr ? 0 :
        class_def->Annotations()->GetOffset();
    class_def_buffer[6] = class_def->GetClassData() == nullptr ? 0 :
        class_def->GetClassData()->GetOffset();
    class_def_buffer[7] = class_def->StaticValues() == nullptr ? 0 :
        class_def->StaticValues()->GetOffset();
    size_t offset = class_def->GetOffset();
    Write(class_def_buffer, class_def->GetSize(), offset);
  }

  for (std::unique_ptr<dex_ir::ClassData>& class_data : header_.GetCollections().ClassDatas()) {
    size_t offset = class_data->GetOffset();
    offset += WriteUleb128(class_data->StaticFields()->size(), offset);
    offset += WriteUleb128(class_data->InstanceFields()->size(), offset);
    offset += WriteUleb128(class_data->DirectMethods()->size(), offset);
    offset += WriteUleb128(class_data->VirtualMethods()->size(), offset);
    offset += WriteEncodedFields(class_data->StaticFields(), offset);
    offset += WriteEncodedFields(class_data->InstanceFields(), offset);
    offset += WriteEncodedMethods(class_data->DirectMethods(), offset);
    offset += WriteEncodedMethods(class_data->VirtualMethods(), offset);
  }
}

struct MapItemContainer {
  MapItemContainer(uint32_t type, uint32_t size, uint32_t offset)
      : type_(type), size_(size), offset_(offset) { }

  bool operator<(const MapItemContainer& other) const {
    return offset_ > other.offset_;
  }

  uint32_t type_;
  uint32_t size_;
  uint32_t offset_;
};

void DexWriter::WriteMapItem() {
  dex_ir::Collections& collection = header_.GetCollections();
  std::priority_queue<MapItemContainer> queue;

  // Header and index section.
  queue.push(MapItemContainer(DexFile::kDexTypeHeaderItem, 1, 0));
  if (collection.StringIdsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeStringIdItem, collection.StringIdsSize(),
        collection.StringIdsOffset()));
  }
  if (collection.TypeIdsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeTypeIdItem, collection.TypeIdsSize(),
        collection.TypeIdsOffset()));
  }
  if (collection.ProtoIdsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeProtoIdItem, collection.ProtoIdsSize(),
        collection.ProtoIdsOffset()));
  }
  if (collection.FieldIdsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeFieldIdItem, collection.FieldIdsSize(),
        collection.FieldIdsOffset()));
  }
  if (collection.MethodIdsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeMethodIdItem, collection.MethodIdsSize(),
        collection.MethodIdsOffset()));
  }
  if (collection.ClassDefsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeClassDefItem, collection.ClassDefsSize(),
        collection.ClassDefsOffset()));
  }

  // Data section.
  queue.push(MapItemContainer(DexFile::kDexTypeMapList, 1, collection.MapItemOffset()));
  if (collection.TypeListsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeTypeList, collection.TypeListsSize(),
        collection.TypeListsOffset()));
  }
  if (collection.AnnotationSetRefListsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeAnnotationSetRefList,
        collection.AnnotationSetRefListsSize(), collection.AnnotationSetRefListsOffset()));
  }
  if (collection.AnnotationSetItemsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeAnnotationSetItem,
        collection.AnnotationSetItemsSize(), collection.AnnotationSetItemsOffset()));
  }
  if (collection.ClassDatasSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeClassDataItem, collection.ClassDatasSize(),
        collection.ClassDatasOffset()));
  }
  if (collection.CodeItemsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeCodeItem, collection.CodeItemsSize(),
        collection.CodeItemsOffset()));
  }
  if (collection.StringDatasSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeStringDataItem, collection.StringDatasSize(),
        collection.StringDatasOffset()));
  }
  if (collection.DebugInfoItemsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeDebugInfoItem, collection.DebugInfoItemsSize(),
        collection.DebugInfoItemsOffset()));
  }
  if (collection.AnnotationItemsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeAnnotationItem, collection.AnnotationItemsSize(),
        collection.AnnotationItemsOffset()));
  }
  if (collection.EncodedArrayItemsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeEncodedArrayItem,
        collection.EncodedArrayItemsSize(), collection.EncodedArrayItemsOffset()));
  }
  if (collection.AnnotationsDirectoryItemsSize() != 0) {
    queue.push(MapItemContainer(DexFile::kDexTypeAnnotationsDirectoryItem,
        collection.AnnotationsDirectoryItemsSize(), collection.AnnotationsDirectoryItemsOffset()));
  }

  uint32_t offset = collection.MapItemOffset();
  uint16_t uint16_buffer[2];
  uint32_t uint32_buffer[2];
  uint16_buffer[1] = 0;
  uint32_buffer[0] = queue.size();
  offset += Write(uint32_buffer, sizeof(uint32_t), offset);
  while (!queue.empty()) {
    const MapItemContainer& map_item = queue.top();
    uint16_buffer[0] = map_item.type_;
    uint32_buffer[0] = map_item.size_;
    uint32_buffer[1] = map_item.offset_;
    offset += Write(uint16_buffer, 2 * sizeof(uint16_t), offset);
    offset += Write(uint32_buffer, 2 * sizeof(uint32_t), offset);
    queue.pop();
  }
}

void DexWriter::WriteHeader() {
  uint32_t buffer[20];
  dex_ir::Collections& collections = header_.GetCollections();
  size_t offset = 0;
  offset += Write(header_.Magic(), 8 * sizeof(uint8_t), offset);
  buffer[0] = header_.Checksum();
  offset += Write(buffer, sizeof(uint32_t), offset);
  offset += Write(header_.Signature(), 20 * sizeof(uint8_t), offset);
  uint32_t file_size = header_.FileSize();
  buffer[0] = file_size;
  buffer[1] = header_.GetSize();
  buffer[2] = header_.EndianTag();
  buffer[3] = header_.LinkSize();
  buffer[4] = header_.LinkOffset();
  buffer[5] = collections.MapItemOffset();
  buffer[6] = collections.StringIdsSize();
  buffer[7] = collections.StringIdsOffset();
  buffer[8] = collections.TypeIdsSize();
  buffer[9] = collections.TypeIdsOffset();
  buffer[10] = collections.ProtoIdsSize();
  buffer[11] = collections.ProtoIdsOffset();
  buffer[12] = collections.FieldIdsSize();
  buffer[13] = collections.FieldIdsOffset();
  buffer[14] = collections.MethodIdsSize();
  buffer[15] = collections.MethodIdsOffset();
  uint32_t class_defs_size = collections.ClassDefsSize();
  uint32_t class_defs_off = collections.ClassDefsOffset();
  buffer[16] = class_defs_size;
  buffer[17] = class_defs_off;
  uint32_t data_off = class_defs_off + class_defs_size * dex_ir::ClassDef::ItemSize();
  uint32_t data_size = file_size - data_off;
  buffer[18] = data_size;
  buffer[19] = data_off;
  Write(buffer, 20 * sizeof(uint32_t), offset);
}

void DexWriter::WriteFile() {
  if (dex_file_.get() == nullptr) {
    fprintf(stderr, "Can't open output dex file\n");
    return;
  }

  header_.GetCollections().CalculateSectionOffsets();

  WriteStrings();
  WriteTypes();
  WriteTypeLists();
  WriteProtos();
  WriteFields();
  WriteMethods();
  WriteEncodedArrays();
  WriteAnnotations();
  WriteAnnotationSets();
  WriteAnnotationSetRefs();
  WriteAnnotationsDirectories();
  WriteDebugInfoItems();
  WriteCodeItems();
  WriteClasses();
  WriteMapItem();
  WriteHeader();
}

void DexWriter::OutputDexFile(dex_ir::Header& header, const char* file_name) {
  LOG(INFO) << "FILE NAME: " << file_name;
  (new DexWriter(header, file_name))->WriteFile();
}

}  // namespace art
