// Copyright 2011 Google Inc. All Rights Reserved.

#include "common_test.h"
#include "dex_file.h"
#include "scoped_ptr.h"

#include <stdio.h>

namespace art {

class DexFileTest : public CommonTest {};

TEST_F(DexFileTest, Open) {
  scoped_ptr<const DexFile> dex(OpenTestDexFile("Nested"));
  ASSERT_TRUE(dex != NULL);
}

// Although this is the same content logically as the Nested test dex,
// the DexFileHeader test is sensitive to subtle changes in the
// contents due to the checksum etc, so we embed the exact input here.
//
// class Nested {
//     class Inner {
//     }
// }
static const char kRawDex[] =
  "ZGV4CjAzNQAQedgAe7gM1B/WHsWJ6L7lGAISGC7yjD2IAwAAcAAAAHhWNBIAAAAAAAAAAMQCAAAP"
  "AAAAcAAAAAcAAACsAAAAAgAAAMgAAAABAAAA4AAAAAMAAADoAAAAAgAAAAABAABIAgAAQAEAAK4B"
  "AAC2AQAAvQEAAM0BAADXAQAA+wEAABsCAAA+AgAAUgIAAF8CAABiAgAAZgIAAHMCAAB5AgAAgQIA"
  "AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABgAAAAAAAAAKAAAABgAAAKgBAAAAAAEA"
  "DQAAAAAAAQAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAIAAAAiAEAAKsCAAAA"
  "AAAAAQAAAAAAAAAFAAAAAAAAAAgAAACYAQAAuAIAAAAAAAACAAAAlAIAAJoCAAABAAAAowIAAAIA"
  "AgABAAAAiAIAAAYAAABbAQAAcBACAAAADgABAAEAAQAAAI4CAAAEAAAAcBACAAAADgBAAQAAAAAA"
  "AAAAAAAAAAAATAEAAAAAAAAAAAAAAAAAAAEAAAABAAY8aW5pdD4ABUlubmVyAA5MTmVzdGVkJElu"
  "bmVyOwAITE5lc3RlZDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2"
  "aWsvYW5ub3RhdGlvbi9Jbm5lckNsYXNzOwAhTGRhbHZpay9hbm5vdGF0aW9uL01lbWJlckNsYXNz"
  "ZXM7ABJMamF2YS9sYW5nL09iamVjdDsAC05lc3RlZC5qYXZhAAFWAAJWTAALYWNjZXNzRmxhZ3MA"
  "BG5hbWUABnRoaXMkMAAFdmFsdWUAAgEABw4AAQAHDjwAAgIBDhgBAgMCCwQADBcBAgQBDhwBGAAA"
  "AQEAAJAgAICABNQCAAABAAGAgATwAgAAEAAAAAAAAAABAAAAAAAAAAEAAAAPAAAAcAAAAAIAAAAH"
  "AAAArAAAAAMAAAACAAAAyAAAAAQAAAABAAAA4AAAAAUAAAADAAAA6AAAAAYAAAACAAAAAAEAAAMQ"
  "AAACAAAAQAEAAAEgAAACAAAAVAEAAAYgAAACAAAAiAEAAAEQAAABAAAAqAEAAAIgAAAPAAAArgEA"
  "AAMgAAACAAAAiAIAAAQgAAADAAAAlAIAAAAgAAACAAAAqwIAAAAQAAABAAAAxAIAAA==";

TEST_F(DexFileTest, Header) {
  scoped_ptr<const DexFile> raw(OpenDexFileBase64(kRawDex, "kRawDex"));
  ASSERT_TRUE(raw != NULL);

  const DexFile::Header& header = raw->GetHeader();
  // TODO: header.magic_
  EXPECT_EQ(0x00d87910U, header.checksum_);
  // TODO: header.signature_
  EXPECT_EQ(904U, header.file_size_);
  EXPECT_EQ(112U, header.header_size_);
  EXPECT_EQ(0U, header.link_size_);
  EXPECT_EQ(0U, header.link_off_);
  EXPECT_EQ(15U, header.string_ids_size_);
  EXPECT_EQ(112U, header.string_ids_off_);
  EXPECT_EQ(7U, header.type_ids_size_);
  EXPECT_EQ(172U, header.type_ids_off_);
  EXPECT_EQ(2U, header.proto_ids_size_);
  EXPECT_EQ(200U, header.proto_ids_off_);
  EXPECT_EQ(1U, header.field_ids_size_);
  EXPECT_EQ(224U, header.field_ids_off_);
  EXPECT_EQ(3U, header.method_ids_size_);
  EXPECT_EQ(232U, header.method_ids_off_);
  EXPECT_EQ(2U, header.class_defs_size_);
  EXPECT_EQ(256U, header.class_defs_off_);
  EXPECT_EQ(584U, header.data_size_);
  EXPECT_EQ(320U, header.data_off_);
}

TEST_F(DexFileTest, ClassDefs) {
  scoped_ptr<const DexFile> raw(OpenTestDexFile("Nested"));
  ASSERT_TRUE(raw != NULL);
  EXPECT_EQ(2U, raw->NumClassDefs());

  const DexFile::ClassDef& c0 = raw->GetClassDef(0);
  EXPECT_STREQ("LNested$Inner;", raw->GetClassDescriptor(c0));

  const DexFile::ClassDef& c1 = raw->GetClassDef(1);
  EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
}

TEST_F(DexFileTest, CreateMethodDescriptor) {
  scoped_ptr<const DexFile> raw(OpenTestDexFile("CreateMethodDescriptor"));
  ASSERT_TRUE(raw != NULL);
  EXPECT_EQ(1U, raw->NumClassDefs());

  const DexFile::ClassDef& class_def = raw->GetClassDef(0);
  ASSERT_STREQ("LCreateMethodDescriptor;", raw->GetClassDescriptor(class_def));

  const byte* class_data = raw->GetClassData(class_def);
  ASSERT_TRUE(class_data != NULL);
  DexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);

  EXPECT_EQ(1u, header.direct_methods_size_);

  // Check the descriptor for the static initializer.
  {
    uint32_t last_idx = 0;
    ASSERT_EQ(1U, header.direct_methods_size_);
    DexFile::Method method;
    raw->dexReadClassDataMethod(&class_data, &method, &last_idx);
    const DexFile::MethodId& method_id = raw->GetMethodId(method.method_idx_);
    uint32_t proto_idx = method_id.proto_idx_;
    const char* name = raw->dexStringById(method_id.name_idx_);
    ASSERT_STREQ("<init>", name);
    int32_t length;
    std::string descriptor(raw->CreateMethodDescriptor(proto_idx, &length));
    ASSERT_EQ("()V", descriptor);
  }

  // Check both virtual methods.
  ASSERT_EQ(2U, header.virtual_methods_size_);
  uint32_t last_idx = 0;

  {
    DexFile::Method method;
    raw->dexReadClassDataMethod(&class_data, &method, &last_idx);
    const DexFile::MethodId& method_id = raw->GetMethodId(method.method_idx_);

    const char* name = raw->dexStringById(method_id.name_idx_);
    ASSERT_STREQ("m1", name);

    uint32_t proto_idx = method_id.proto_idx_;
    int32_t length;
    std::string descriptor(raw->CreateMethodDescriptor(proto_idx, &length));
    ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", descriptor);
  }

  {
    DexFile::Method method;
    raw->dexReadClassDataMethod(&class_data, &method, &last_idx);
    const DexFile::MethodId& method_id = raw->GetMethodId(method.method_idx_);

    const char* name = raw->dexStringById(method_id.name_idx_);
    ASSERT_STREQ("m2", name);

    uint32_t proto_idx = method_id.proto_idx_;
    int32_t length;
    std::string descriptor(raw->CreateMethodDescriptor(proto_idx, &length));
    ASSERT_EQ("(ZSC)LCreateMethodDescriptor;", descriptor);
  }

}

}  // namespace art
