/*
 * 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.
 */

#include "androidfw/LoadedArsc.h"

#include "androidfw/ResourceUtils.h"

#include "TestHelpers.h"
#include "data/basic/R.h"
#include "data/libclient/R.h"
#include "data/sparse/R.h"
#include "data/styles/R.h"

namespace app = com::android::app;
namespace basic = com::android::basic;
namespace libclient = com::android::libclient;
namespace sparse = com::android::sparse;

using ::testing::Eq;
using ::testing::Ge;
using ::testing::IsNull;
using ::testing::NotNull;
using ::testing::SizeIs;
using ::testing::StrEq;

namespace android {

TEST(LoadedArscTest, LoadSinglePackageArsc) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/styles/styles.apk", "resources.arsc",
                                      &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package =
      loaded_arsc->GetPackageById(get_package_id(app::R::string::string_one));
  ASSERT_THAT(package, NotNull());
  EXPECT_THAT(package->GetPackageName(), StrEq("com.android.app"));
  EXPECT_THAT(package->GetPackageId(), Eq(0x7f));

  const uint8_t type_index = get_type_id(app::R::string::string_one) - 1;
  const uint16_t entry_index = get_entry_id(app::R::string::string_one);

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_count, Ge(1u));

  const ResTable_type* type = type_spec->types[0];
  ASSERT_THAT(type, NotNull());
  ASSERT_THAT(LoadedPackage::GetEntry(type, entry_index), NotNull());
}

TEST(LoadedArscTest, LoadSparseEntryApp) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/sparse/sparse.apk", "resources.arsc",
                                      &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package =
      loaded_arsc->GetPackageById(get_package_id(sparse::R::integer::foo_9));
  ASSERT_THAT(package, NotNull());

  const uint8_t type_index = get_type_id(sparse::R::integer::foo_9) - 1;
  const uint16_t entry_index = get_entry_id(sparse::R::integer::foo_9);

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_count, Ge(1u));

  const ResTable_type* type = type_spec->types[0];
  ASSERT_THAT(type, NotNull());
  ASSERT_THAT(LoadedPackage::GetEntry(type, entry_index), NotNull());
}

TEST(LoadedArscTest, LoadSharedLibrary) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/lib_one/lib_one.apk", "resources.arsc",
                                      &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
  ASSERT_THAT(loaded_arsc, NotNull());

  const auto& packages = loaded_arsc->GetPackages();
  ASSERT_THAT(packages, SizeIs(1u));
  EXPECT_TRUE(packages[0]->IsDynamic());
  EXPECT_THAT(packages[0]->GetPackageName(), StrEq("com.android.lib_one"));
  EXPECT_THAT(packages[0]->GetPackageId(), Eq(0));

  const auto& dynamic_pkg_map = packages[0]->GetDynamicPackageMap();

  // The library has no dependencies.
  ASSERT_TRUE(dynamic_pkg_map.empty());
}

TEST(LoadedArscTest, LoadAppLinkedAgainstSharedLibrary) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/libclient/libclient.apk",
                                      "resources.arsc", &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
  ASSERT_THAT(loaded_arsc, NotNull());

  const auto& packages = loaded_arsc->GetPackages();
  ASSERT_THAT(packages, SizeIs(1u));
  EXPECT_FALSE(packages[0]->IsDynamic());
  EXPECT_THAT(packages[0]->GetPackageName(), StrEq("com.android.libclient"));
  EXPECT_THAT(packages[0]->GetPackageId(), Eq(0x7f));

  const auto& dynamic_pkg_map = packages[0]->GetDynamicPackageMap();

  // The library has two dependencies.
  ASSERT_THAT(dynamic_pkg_map, SizeIs(2u));
  EXPECT_THAT(dynamic_pkg_map[0].package_name, StrEq("com.android.lib_one"));
  EXPECT_THAT(dynamic_pkg_map[0].package_id, Eq(0x02));

  EXPECT_THAT(dynamic_pkg_map[1].package_name, StrEq("com.android.lib_two"));
  EXPECT_THAT(dynamic_pkg_map[1].package_id, Eq(0x03));
}

TEST(LoadedArscTest, LoadAppAsSharedLibrary) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/appaslib/appaslib.apk",
                                      "resources.arsc", &contents));

  std::unique_ptr<const LoadedArsc> loaded_arsc =
      LoadedArsc::Load(StringPiece(contents), nullptr /*loaded_idmap*/, false /*system*/,
                       true /*load_as_shared_library*/);
  ASSERT_THAT(loaded_arsc, NotNull());

  const auto& packages = loaded_arsc->GetPackages();
  ASSERT_THAT(packages, SizeIs(1u));
  EXPECT_TRUE(packages[0]->IsDynamic());
  EXPECT_THAT(packages[0]->GetPackageId(), Eq(0x7f));
}

TEST(LoadedArscTest, LoadFeatureSplit) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/feature/feature.apk", "resources.arsc",
                                      &contents));
  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package =
      loaded_arsc->GetPackageById(get_package_id(basic::R::string::test3));
  ASSERT_THAT(package, NotNull());

  uint8_t type_index = get_type_id(basic::R::string::test3) - 1;
  uint8_t entry_index = get_entry_id(basic::R::string::test3);

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(type_index);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_count, Ge(1u));
  ASSERT_THAT(type_spec->types[0], NotNull());

  size_t len;
  const char16_t* type_name16 =
      package->GetTypeStringPool()->stringAt(type_spec->type_spec->id - 1, &len);
  ASSERT_THAT(type_name16, NotNull());
  EXPECT_THAT(util::Utf16ToUtf8(StringPiece16(type_name16, len)), StrEq("string"));

  ASSERT_THAT(LoadedPackage::GetEntry(type_spec->types[0], entry_index), NotNull());
}

class MockLoadedIdmap : public LoadedIdmap {
 public:
  MockLoadedIdmap() : LoadedIdmap() {
    local_header_.magic = kIdmapMagic;
    local_header_.version = kIdmapCurrentVersion;
    local_header_.target_package_id = 0x08;
    local_header_.type_count = 1;
    header_ = &local_header_;

    entry_header = util::unique_cptr<IdmapEntry_header>(
        (IdmapEntry_header*)::malloc(sizeof(IdmapEntry_header) + sizeof(uint32_t)));
    entry_header->target_type_id = 0x03;
    entry_header->overlay_type_id = 0x02;
    entry_header->entry_id_offset = 1;
    entry_header->entry_count = 1;
    entry_header->entries[0] = 0x00000000u;
    type_map_[entry_header->overlay_type_id] = entry_header.get();
  }

 private:
  Idmap_header local_header_;
  util::unique_cptr<IdmapEntry_header> entry_header;
};

TEST(LoadedArscTest, LoadOverlay) {
  std::string contents;
  ASSERT_TRUE(ReadFileFromZipToString(GetTestDataPath() + "/overlay/overlay.apk", "resources.arsc",
                                      &contents));

  MockLoadedIdmap loaded_idmap;

  std::unique_ptr<const LoadedArsc> loaded_arsc =
      LoadedArsc::Load(StringPiece(contents), &loaded_idmap);
  ASSERT_THAT(loaded_arsc, NotNull());

  const LoadedPackage* package = loaded_arsc->GetPackageById(0x08u);
  ASSERT_THAT(package, NotNull());

  const TypeSpec* type_spec = package->GetTypeSpecByTypeIndex(0x03u - 1);
  ASSERT_THAT(type_spec, NotNull());
  ASSERT_THAT(type_spec->type_count, Ge(1u));
  ASSERT_THAT(type_spec->types[0], NotNull());

  // The entry being overlaid doesn't exist at the original entry index.
  ASSERT_THAT(LoadedPackage::GetEntry(type_spec->types[0], 0x0001u), IsNull());

  // Since this is an overlay, the actual entry ID must be mapped.
  ASSERT_THAT(type_spec->idmap_entries, NotNull());
  uint16_t target_entry_id = 0u;
  ASSERT_TRUE(LoadedIdmap::Lookup(type_spec->idmap_entries, 0x0001u, &target_entry_id));
  ASSERT_THAT(target_entry_id, Eq(0x0u));
  ASSERT_THAT(LoadedPackage::GetEntry(type_spec->types[0], 0x0000), NotNull());
}

// structs with size fields (like Res_value, ResTable_entry) should be
// backwards and forwards compatible (aka checking the size field against
// sizeof(Res_value) might not be backwards compatible.
TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }

}  // namespace android
