/*
 * 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.
 *
 * Implementation file of the dexlayout utility.
 *
 * This is a tool to read dex files into an internal representation,
 * reorganize the representation, and emit dex files with a better
 * file layout.
 */

#include "dex_ir.h"

#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file_exception_helpers.h"
#include "dex/dex_instruction-inl.h"
#include "dex_ir_builder.h"

namespace art {
namespace dex_ir {

static uint32_t HeaderOffset([[maybe_unused]] const dex_ir::Header* header) { return 0; }

static uint32_t HeaderSize([[maybe_unused]] const dex_ir::Header* header) {
  // Size is in elements, so there is only one header.
  return 1;
}

// The description of each dex file section type.
struct FileSectionDescriptor {
 public:
  std::string name;
  uint16_t type;
  // A function that when applied to a collection object, gives the size of the section.
  std::function<uint32_t(dex_ir::Header*)> size_fn;
  // A function that when applied to a collection object, gives the offset of the section.
  std::function<uint32_t(dex_ir::Header*)> offset_fn;
};

static const FileSectionDescriptor kFileSectionDescriptors[] = {
  {
    "Header",
    DexFile::kDexTypeHeaderItem,
    &HeaderSize,
    &HeaderOffset,
  }, {
    "StringId",
    DexFile::kDexTypeStringIdItem,
    [](const dex_ir::Header* h) { return h->StringIds().Size(); },
    [](const dex_ir::Header* h) { return h->StringIds().GetOffset(); }
  }, {
    "TypeId",
    DexFile::kDexTypeTypeIdItem,
    [](const dex_ir::Header* h) { return h->TypeIds().Size(); },
    [](const dex_ir::Header* h) { return h->TypeIds().GetOffset(); }
  }, {
    "ProtoId",
    DexFile::kDexTypeProtoIdItem,
    [](const dex_ir::Header* h) { return h->ProtoIds().Size(); },
    [](const dex_ir::Header* h) { return h->ProtoIds().GetOffset(); }
  }, {
    "FieldId",
    DexFile::kDexTypeFieldIdItem,
    [](const dex_ir::Header* h) { return h->FieldIds().Size(); },
    [](const dex_ir::Header* h) { return h->FieldIds().GetOffset(); }
  }, {
    "MethodId",
    DexFile::kDexTypeMethodIdItem,
    [](const dex_ir::Header* h) { return h->MethodIds().Size(); },
    [](const dex_ir::Header* h) { return h->MethodIds().GetOffset(); }
  }, {
    "ClassDef",
    DexFile::kDexTypeClassDefItem,
    [](const dex_ir::Header* h) { return h->ClassDefs().Size(); },
    [](const dex_ir::Header* h) { return h->ClassDefs().GetOffset(); }
  }, {
    "CallSiteId",
    DexFile::kDexTypeCallSiteIdItem,
    [](const dex_ir::Header* h) { return h->CallSiteIds().Size(); },
    [](const dex_ir::Header* h) { return h->CallSiteIds().GetOffset(); }
  }, {
    "MethodHandle",
    DexFile::kDexTypeMethodHandleItem,
    [](const dex_ir::Header* h) { return h->MethodHandleItems().Size(); },
    [](const dex_ir::Header* h) { return h->MethodHandleItems().GetOffset(); }
  }, {
    "StringData",
    DexFile::kDexTypeStringDataItem,
    [](const dex_ir::Header* h) { return h->StringDatas().Size(); },
    [](const dex_ir::Header* h) { return h->StringDatas().GetOffset(); }
  }, {
    "TypeList",
    DexFile::kDexTypeTypeList,
    [](const dex_ir::Header* h) { return h->TypeLists().Size(); },
    [](const dex_ir::Header* h) { return h->TypeLists().GetOffset(); }
  }, {
    "EncArr",
    DexFile::kDexTypeEncodedArrayItem,
    [](const dex_ir::Header* h) { return h->EncodedArrayItems().Size(); },
    [](const dex_ir::Header* h) { return h->EncodedArrayItems().GetOffset(); }
  }, {
    "Annotation",
    DexFile::kDexTypeAnnotationItem,
    [](const dex_ir::Header* h) { return h->AnnotationItems().Size(); },
    [](const dex_ir::Header* h) { return h->AnnotationItems().GetOffset(); }
  }, {
    "AnnoSet",
    DexFile::kDexTypeAnnotationSetItem,
    [](const dex_ir::Header* h) { return h->AnnotationSetItems().Size(); },
    [](const dex_ir::Header* h) { return h->AnnotationSetItems().GetOffset(); }
  }, {
    "AnnoSetRL",
    DexFile::kDexTypeAnnotationSetRefList,
    [](const dex_ir::Header* h) { return h->AnnotationSetRefLists().Size(); },
    [](const dex_ir::Header* h) { return h->AnnotationSetRefLists().GetOffset(); }
  }, {
    "AnnoDir",
    DexFile::kDexTypeAnnotationsDirectoryItem,
    [](const dex_ir::Header* h) { return h->AnnotationsDirectoryItems().Size(); },
    [](const dex_ir::Header* h) { return h->AnnotationsDirectoryItems().GetOffset(); }
  }, {
    "DebugInfo",
    DexFile::kDexTypeDebugInfoItem,
    [](const dex_ir::Header* h) { return h->DebugInfoItems().Size(); },
    [](const dex_ir::Header* h) { return h->DebugInfoItems().GetOffset(); }
  }, {
    "CodeItem",
    DexFile::kDexTypeCodeItem,
    [](const dex_ir::Header* h) { return h->CodeItems().Size(); },
    [](const dex_ir::Header* h) { return h->CodeItems().GetOffset(); }
  }, {
    "ClassData",
    DexFile::kDexTypeClassDataItem,
    [](const dex_ir::Header* h) { return h->ClassDatas().Size(); },
    [](const dex_ir::Header* h) { return h->ClassDatas().GetOffset(); }
  }
};

std::vector<dex_ir::DexFileSection> GetSortedDexFileSections(dex_ir::Header* header,
                                                             dex_ir::SortDirection direction) {
  std::vector<dex_ir::DexFileSection> sorted_sections;
  // Build the table that will map from offset to color
  for (const FileSectionDescriptor& s : kFileSectionDescriptors) {
    sorted_sections.push_back(dex_ir::DexFileSection(s.name,
                                                     s.type,
                                                     s.size_fn(header),
                                                     s.offset_fn(header)));
  }
  // Sort by offset.
  std::sort(sorted_sections.begin(),
            sorted_sections.end(),
            [=](dex_ir::DexFileSection& a, dex_ir::DexFileSection& b) {
              if (direction == SortDirection::kSortDescending) {
                return a.offset > b.offset;
              } else {
                return a.offset < b.offset;
              }
            });
  return sorted_sections;
}

}  // namespace dex_ir
}  // namespace art
