/*
 * Copyright (C) 2018 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 <android-base/file.h>

#include <cstdio>  // fclose
#include <fstream>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "R.h"
#include "TestConstants.h"
#include "TestHelpers.h"
#include "android-base/macros.h"
#include "androidfw/ApkAssets.h"
#include "androidfw/ResourceUtils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "idmap2/BinaryStreamVisitor.h"
#include "idmap2/CommandLineOptions.h"
#include "idmap2/Idmap.h"
#include "idmap2/LogInfo.h"

using ::testing::NotNull;

using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;

namespace android::idmap2 {

#define ASSERT_TARGET_ENTRY(entry, target_resid, overlay_resid) \
  ASSERT_EQ((entry).target_id, (target_resid));                 \
  ASSERT_EQ((entry).overlay_id, (overlay_resid))

#define ASSERT_TARGET_INLINE_ENTRY(entry, target_resid, ex_config, expected_type, expected_value) \
  ASSERT_EQ((entry).target_id, target_resid);                                                     \
  ASSERT_EQ((entry).values.begin()->first.to_string(), (ex_config));                              \
  ASSERT_EQ((entry).values.begin()->second.data_type, (expected_type));                           \
  ASSERT_EQ((entry).values.begin()->second.data_value, (expected_value))

#define ASSERT_OVERLAY_ENTRY(entry, overlay_resid, target_resid) \
  ASSERT_EQ((entry).overlay_id, (overlay_resid));                \
  ASSERT_EQ((entry).target_id, (target_resid))

TEST(IdmapTests, TestCanonicalIdmapPathFor) {
  ASSERT_EQ(Idmap::CanonicalIdmapPathFor("/foo", "/vendor/overlay/bar.apk"),
            "/foo/vendor@overlay@bar.apk@idmap");
}

TEST(IdmapTests, CreateIdmapHeaderFromBinaryStream) {
  std::string raw(reinterpret_cast<const char*>(kIdmapRawData), kIdmapRawDataLen);
  std::istringstream stream(raw);
  std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
  ASSERT_THAT(header, NotNull());
  ASSERT_EQ(header->GetMagic(), 0x504d4449U);
  ASSERT_EQ(header->GetVersion(), 11);
  ASSERT_EQ(header->GetTargetCrc(), 0x1234U);
  ASSERT_EQ(header->GetOverlayCrc(), 0x5678U);
  ASSERT_EQ(header->GetFulfilledPolicies(), 0x11);
  ASSERT_EQ(header->GetEnforceOverlayable(), true);
  ASSERT_EQ(header->GetTargetPath(), "targetX.apk");
  ASSERT_EQ(header->GetOverlayPath(), "overlayX.apk");
  ASSERT_EQ(header->GetDebugInfo(), "debug");
}

TEST(IdmapTests, IdmapFailParsingDifferentVersion) {
  constexpr size_t kJunkSize = 2000;
  std::stringstream stream;
  stream << android::kIdmapMagic;
  stream << 0xffffffffU;
  stream << std::string(kJunkSize, static_cast<char>(0xffU));
  ASSERT_FALSE(Idmap::FromBinaryStream(stream));
}

TEST(IdmapTests, IdmapFailParsingDifferentMagic) {
  constexpr size_t kJunkSize = 2000;
  std::stringstream stream;
  stream << 0xffffffffU;
  stream << android::kIdmapCurrentVersion;
  stream << std::string(kJunkSize, static_cast<char>(0xffU));
  ASSERT_FALSE(Idmap::FromBinaryStream(stream));
}

TEST(IdmapTests, CreateIdmapConstraintsFromBinaryStream) {
  std::string raw(reinterpret_cast<const char*>(kIdmapRawData), kIdmapRawDataLen);
  std::istringstream stream(raw);
  std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
  std::unique_ptr<const IdmapConstraints> constraints = IdmapConstraints::FromBinaryStream(stream);
  ASSERT_THAT(constraints, NotNull());
  ASSERT_EQ(constraints->constraints.size(), 2);
  IdmapConstraint constraint1{.constraint_type = 0, .constraint_value = 1};
  IdmapConstraint constraint2{.constraint_type = 1, .constraint_value = 2};
  ASSERT_NE(constraints->constraints.find(constraint1), constraints->constraints.end());
  ASSERT_NE(constraints->constraints.find(constraint2), constraints->constraints.end());
}

TEST(IdmapTests, CreateIdmapDataHeaderFromBinaryStream) {
  const size_t offset = kIdmapRawDataOffset;
  std::string raw(reinterpret_cast<const char*>(kIdmapRawData + offset), kIdmapRawDataLen - offset);
  std::istringstream stream(raw);

  std::unique_ptr<const IdmapData::Header> header = IdmapData::Header::FromBinaryStream(stream);
  ASSERT_THAT(header, NotNull());
  ASSERT_EQ(header->GetTargetEntryCount(), 0x03);
  ASSERT_EQ(header->GetOverlayEntryCount(), 0x03);
}

TEST(IdmapTests, CreateIdmapDataFromBinaryStream) {
  const size_t offset = kIdmapRawDataOffset;
  std::string raw(reinterpret_cast<const char*>(kIdmapRawData + offset), kIdmapRawDataLen - offset);
  std::istringstream stream(raw);

  std::unique_ptr<const IdmapData> data = IdmapData::FromBinaryStream(stream);
  ASSERT_THAT(data, NotNull());

  const auto& target_entries = data->GetTargetEntries();
  ASSERT_EQ(target_entries.size(), 3U);
  ASSERT_TARGET_ENTRY(target_entries[0], 0x7f020000, 0x7f020000);
  ASSERT_TARGET_ENTRY(target_entries[1], 0x7f030000, 0x7f030000);
  ASSERT_TARGET_ENTRY(target_entries[2], 0x7f030002, 0x7f030001);

  const auto& target_inline_entries = data->GetTargetInlineEntries();
  ASSERT_EQ(target_inline_entries.size(), 1U);
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000,  "land-xxhdpi-v7",
                             Res_value::TYPE_INT_HEX, 0x12345678);

  const auto& overlay_entries = data->GetOverlayEntries();
  ASSERT_EQ(target_entries.size(), 3U);
  ASSERT_OVERLAY_ENTRY(overlay_entries[0], 0x7f020000, 0x7f020000);
  ASSERT_OVERLAY_ENTRY(overlay_entries[1], 0x7f030000, 0x7f030000);
  ASSERT_OVERLAY_ENTRY(overlay_entries[2], 0x7f030001, 0x7f030002);
}

TEST(IdmapTests, CreateIdmapFromBinaryStream) {
  std::string raw(reinterpret_cast<const char*>(kIdmapRawData), kIdmapRawDataLen);
  std::istringstream stream(raw);

  auto result = Idmap::FromBinaryStream(stream);
  ASSERT_TRUE(result);
  const auto idmap = std::move(*result);

  ASSERT_THAT(idmap->GetHeader(), NotNull());
  ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 11);
  ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), 0x1234U);
  ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), 0x5678U);
  ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), kIdmapRawDataPolicies);
  ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true);
  ASSERT_EQ(idmap->GetHeader()->GetTargetPath(), kIdmapRawTargetPath);
  ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), kIdmapRawOverlayPath);
  ASSERT_EQ(idmap->GetHeader()->GetOverlayName(), kIdmapRawOverlayName);

  const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
  ASSERT_EQ(dataBlocks.size(), 1U);

  const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
  ASSERT_THAT(data, NotNull());

  const auto& target_entries = data->GetTargetEntries();
  ASSERT_EQ(target_entries.size(), 3U);
  ASSERT_TARGET_ENTRY(target_entries[0], 0x7f020000, 0x7f020000);
  ASSERT_TARGET_ENTRY(target_entries[1], 0x7f030000, 0x7f030000);
  ASSERT_TARGET_ENTRY(target_entries[2], 0x7f030002, 0x7f030001);

  const auto& target_inline_entries = data->GetTargetInlineEntries();
  ASSERT_EQ(target_inline_entries.size(), 1U);
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], 0x7f040000,  "land-xxhdpi-v7",
                             Res_value::TYPE_INT_HEX, 0x12345678);

  const auto& overlay_entries = data->GetOverlayEntries();
  ASSERT_EQ(target_entries.size(), 3U);
  ASSERT_OVERLAY_ENTRY(overlay_entries[0], 0x7f020000, 0x7f020000);
  ASSERT_OVERLAY_ENTRY(overlay_entries[1], 0x7f030000, 0x7f030000);
  ASSERT_OVERLAY_ENTRY(overlay_entries[2], 0x7f030001, 0x7f030002);
}

TEST(IdmapTests, GracefullyFailToCreateIdmapFromCorruptBinaryStream) {
  std::string raw(reinterpret_cast<const char*>(kIdmapRawData),
                  10);  // data too small
  std::istringstream stream(raw);

  const auto result = Idmap::FromBinaryStream(stream);
  ASSERT_FALSE(result);
}

TEST(IdmapTests, CreateIdmapHeaderFromApkAssets) {
  std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
  std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk";

  auto target = TargetResourceContainer::FromPath(target_apk_path);
  ASSERT_TRUE(target);

  auto overlay = OverlayResourceContainer::FromPath(overlay_apk_path);
  ASSERT_TRUE(overlay);

  auto constraints = std::make_unique<const IdmapConstraints>();
  auto idmap_result = Idmap::FromContainers(
      **target, **overlay, TestConstants::OVERLAY_NAME_ALL_POLICIES, PolicyFlags::PUBLIC,
      /* enforce_overlayable */ true, std::move(constraints));
  ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage();
  auto& idmap = *idmap_result;
  ASSERT_THAT(idmap, NotNull());

  ASSERT_THAT(idmap->GetHeader(), NotNull());
  ASSERT_EQ(idmap->GetHeader()->GetMagic(), 0x504d4449U);
  ASSERT_EQ(idmap->GetHeader()->GetVersion(), 11);
  ASSERT_EQ(idmap->GetHeader()->GetTargetCrc(), android::idmap2::TestConstants::TARGET_CRC);
  ASSERT_EQ(idmap->GetHeader()->GetOverlayCrc(), android::idmap2::TestConstants::OVERLAY_CRC);
  ASSERT_EQ(idmap->GetHeader()->GetFulfilledPolicies(), PolicyFlags::PUBLIC);
  ASSERT_EQ(idmap->GetHeader()->GetEnforceOverlayable(), true);
  ASSERT_EQ(idmap->GetHeader()->GetTargetPath(), target_apk_path);
  ASSERT_EQ(idmap->GetHeader()->GetOverlayPath(), overlay_apk_path);
  ASSERT_EQ(idmap->GetHeader()->GetOverlayName(), TestConstants::OVERLAY_NAME_ALL_POLICIES);
}

TEST(IdmapTests, TargetContainerWorksAfterError) {
  auto target = TargetResourceContainer::FromPath(GetTestDataPath() + "/target/target-bad.apk");
  ASSERT_TRUE(target);

  auto crc = target->get()->GetCrc();
  ASSERT_TRUE(crc);

  // This call tries to construct the full ApkAssets state, and fails.
  ASSERT_FALSE(target->get()->DefinesOverlayable());
  auto crc2 = target->get()->GetCrc();
  ASSERT_TRUE(crc2);
  EXPECT_EQ(*crc, *crc2);
}

TEST(IdmapTests, CreateIdmapDataFromApkAssets) {
  std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
  std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk";

  auto target = TargetResourceContainer::FromPath(target_apk_path);
  ASSERT_TRUE(target);

  auto overlay = OverlayResourceContainer::FromPath(overlay_apk_path);
  ASSERT_TRUE(overlay);

  auto constraints = std::make_unique<const IdmapConstraints>();
  auto idmap_result = Idmap::FromContainers(
      **target, **overlay, TestConstants::OVERLAY_NAME_DEFAULT, PolicyFlags::PUBLIC,
      /* enforce_overlayable */ true, std::move(constraints));
  ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage();
  auto& idmap = *idmap_result;
  ASSERT_THAT(idmap, NotNull());

  const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
  ASSERT_EQ(dataBlocks.size(), 1U);

  const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
  ASSERT_THAT(data, NotNull());

  const auto& target_entries = data->GetTargetEntries();
  ASSERT_EQ(target_entries.size(), 4U);
  ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1, R::overlay::integer::int1);
  ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1, R::overlay::string::str1);
  ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3, R::overlay::string::str3);
  ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4, R::overlay::string::str4);

  const auto& target_inline_entries = data->GetTargetInlineEntries();
  ASSERT_EQ(target_inline_entries.size(), 0U);

  const auto& overlay_entries = data->GetOverlayEntries();
  ASSERT_EQ(target_entries.size(), 4U);
  ASSERT_OVERLAY_ENTRY(overlay_entries[0], R::overlay::integer::int1, R::target::integer::int1);
  ASSERT_OVERLAY_ENTRY(overlay_entries[1], R::overlay::string::str1, R::target::string::str1);
  ASSERT_OVERLAY_ENTRY(overlay_entries[2], R::overlay::string::str3, R::target::string::str3);
  ASSERT_OVERLAY_ENTRY(overlay_entries[3], R::overlay::string::str4, R::target::string::str4);
}

TEST(IdmapTests, FabricatedOverlay) {
  std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
  auto target = TargetResourceContainer::FromPath(target_apk_path);
  ASSERT_TRUE(target);

  auto path = GetTestDataPath() + "/overlay/res/drawable/android.png";
  auto fd = android::base::unique_fd(::open(path.c_str(), O_RDONLY | O_CLOEXEC));
  ASSERT_TRUE(fd > 0) << "errno " << errno << " for path " << path;

  auto frro = FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "test.target")
                  .SetOverlayable("TestResources")
                  .SetResourceValue("integer/int1", Res_value::TYPE_INT_DEC, 2U, "land-xxhdpi-v7")
                  .SetResourceValue("string/str1", Res_value::TYPE_REFERENCE, 0x7f010000, "land")
                  .SetResourceValue("string/str2", Res_value::TYPE_STRING, "foobar", "xxhdpi-v7")
                  .SetResourceValue("drawable/dr1", fd, 0, 8341, "port-xxhdpi-v7", false)
                  .setFrroPath("/foo/bar/biz.frro")
                  .Build();

  ASSERT_TRUE(frro);
  TempFrroFile tf;
  std::ofstream out(tf.path);
  ASSERT_TRUE((*frro).ToBinaryStream(out));
  out.close();

  auto overlay = OverlayResourceContainer::FromPath(tf.path);
  ASSERT_TRUE(overlay);

  auto constraints = std::make_unique<const IdmapConstraints>();
  auto idmap_result = Idmap::FromContainers(**target, **overlay, "SandTheme", PolicyFlags::PUBLIC,
                                            /* enforce_overlayable */ true, std::move(constraints));
  ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage();
  auto& idmap = *idmap_result;
  ASSERT_THAT(idmap, NotNull());

  const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
  ASSERT_EQ(dataBlocks.size(), 1U);

  const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
  ASSERT_THAT(data, NotNull());
  ASSERT_EQ(data->GetTargetEntries().size(), 0U);
  ASSERT_EQ(data->GetOverlayEntries().size(), 0U);

  auto string_pool_data = data->GetStringPoolData();
  auto string_pool = ResStringPool(string_pool_data.data(), string_pool_data.size(), false);

  std::u16string expected_uri = u"frro://foo/bar/biz.frro?offset=16&size=8341";
  uint32_t uri_index
      = string_pool.indexOfString(expected_uri.data(), expected_uri.length()).value_or(-1);

  const auto& target_inline_entries = data->GetTargetInlineEntries();
  ASSERT_EQ(target_inline_entries.size(), 4U);
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::drawable::dr1, "port-xxhdpi-v7",
                             Res_value::TYPE_STRING, uri_index);
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::integer::int1, "land-xxhdpi-v7",
                             Res_value::TYPE_INT_DEC, 2U);
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[2], R::target::string::str1, "land",
                             Res_value::TYPE_REFERENCE, 0x7f010000);
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[3], R::target::string::str2, "xxhdpi-v7",
                             Res_value::TYPE_STRING,
                             (uint32_t) (string_pool.indexOfString(u"foobar", 6)).value_or(-1));
}

TEST(IdmapTests, FailCreateIdmapInvalidName) {
  std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
  std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay.apk";

  auto target = TargetResourceContainer::FromPath(target_apk_path);
  ASSERT_TRUE(target);

  auto overlay = OverlayResourceContainer::FromPath(overlay_apk_path);
  ASSERT_TRUE(overlay);

  {
    auto constraints = std::make_unique<const IdmapConstraints>();
    auto idmap_result = Idmap::FromContainers(**target, **overlay, "", PolicyFlags::PUBLIC,
                                              /* enforce_overlayable */ true,
                                              std::move(constraints));
    ASSERT_FALSE(idmap_result);
  }
  {
    auto constraints = std::make_unique<const IdmapConstraints>();
    auto idmap_result = Idmap::FromContainers(**target, **overlay, "unknown", PolicyFlags::PUBLIC,
                                              /* enforce_overlayable */ true,
                                              std::move(constraints));
    ASSERT_FALSE(idmap_result);
  }
}

TEST(IdmapTests, CreateIdmapDataFromApkAssetsSharedLibOverlay) {
  std::string target_apk_path = GetTestDataPath() + "/target/target.apk";
  std::string overlay_apk_path = GetTestDataPath() + "/overlay/overlay-shared.apk";

  auto target = TargetResourceContainer::FromPath(target_apk_path);
  ASSERT_TRUE(target);

  auto overlay = OverlayResourceContainer::FromPath(overlay_apk_path);
  ASSERT_TRUE(overlay);

  auto constraints = std::make_unique<const IdmapConstraints>();
  auto idmap_result = Idmap::FromContainers(
      **target, **overlay, TestConstants::OVERLAY_NAME_DEFAULT, PolicyFlags::PUBLIC,
      /* enforce_overlayable */ true, std::move(constraints));
  ASSERT_TRUE(idmap_result) << idmap_result.GetErrorMessage();
  auto& idmap = *idmap_result;
  ASSERT_THAT(idmap, NotNull());

  const std::vector<std::unique_ptr<const IdmapData>>& dataBlocks = idmap->GetData();
  ASSERT_EQ(dataBlocks.size(), 1U);

  const std::unique_ptr<const IdmapData>& data = dataBlocks[0];
  ASSERT_THAT(data, NotNull());

  const auto& target_entries = data->GetTargetEntries();
  ASSERT_EQ(target_entries.size(), 4U);
  ASSERT_TARGET_ENTRY(target_entries[0], R::target::integer::int1,
                      fix_package_id(R::overlay::integer::int1, 0));
  ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str1,
                      fix_package_id(R::overlay::string::str1, 0));
  ASSERT_TARGET_ENTRY(target_entries[2], R::target::string::str3,
                      fix_package_id(R::overlay::string::str3, 0));
  ASSERT_TARGET_ENTRY(target_entries[3], R::target::string::str4,
                      fix_package_id(R::overlay::string::str4, 0));

  const auto& target_inline_entries = data->GetTargetInlineEntries();
  ASSERT_EQ(target_inline_entries.size(), 0U);

  const auto& overlay_entries = data->GetOverlayEntries();
  ASSERT_EQ(target_entries.size(), 4U);
  ASSERT_OVERLAY_ENTRY(overlay_entries[0], fix_package_id(R::overlay::integer::int1, 0),
                       R::target::integer::int1);
  ASSERT_OVERLAY_ENTRY(overlay_entries[1], fix_package_id(R::overlay::string::str1, 0),
                       R::target::string::str1);
  ASSERT_OVERLAY_ENTRY(overlay_entries[2], fix_package_id(R::overlay::string::str3, 0),
                       R::target::string::str3);
  ASSERT_OVERLAY_ENTRY(overlay_entries[3], fix_package_id(R::overlay::string::str4, 0),
                       R::target::string::str4);
}

Result<std::unique_ptr<const IdmapData>> TestIdmapDataFromApkAssets(
    const std::string& local_target_path, const std::string& local_overlay_path,
    const std::string& overlay_name, const PolicyBitmask& fulfilled_policies,
    bool enforce_overlayable) {
  const std::string target_path(GetTestDataPath() + local_target_path);
  auto target = TargetResourceContainer::FromPath(target_path);
  if (!target) {
    return Error(R"(Failed to load target "%s")", target_path.c_str());
  }

  const std::string overlay_path(GetTestDataPath() + local_overlay_path);
  auto overlay = OverlayResourceContainer::FromPath(overlay_path);
  if (!overlay) {
    return Error(R"(Failed to load overlay "%s")", overlay_path.c_str());
  }

  auto overlay_info = (*overlay)->FindOverlayInfo(overlay_name);
  if (!overlay_info) {
    return Error(R"(Failed to find overlay name "%s")", overlay_name.c_str());
  }

  LogInfo log_info;
  auto mapping = ResourceMapping::FromContainers(**target, **overlay, *overlay_info,
                                                 fulfilled_policies, enforce_overlayable, log_info);
  if (!mapping) {
    return mapping.GetError();
  }

  return IdmapData::FromResourceMapping(*mapping);
}

TEST(IdmapTests, CreateIdmapDataDoNotRewriteNonOverlayResourceId) {
  auto idmap_data = TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk",
                                               "DifferentPackages", PolicyFlags::PUBLIC,
                                               /* enforce_overlayable */ false);

  ASSERT_TRUE(idmap_data) << idmap_data.GetErrorMessage();
  auto& data = *idmap_data;

  const auto& target_entries = data->GetTargetEntries();
  ASSERT_EQ(target_entries.size(), 2U);
  ASSERT_TARGET_ENTRY(target_entries[0], R::target::string::str1,
                      0x0104000a);  // -> android:string/ok
  ASSERT_TARGET_ENTRY(target_entries[1], R::target::string::str3, R::overlay::string::str3);

  const auto& target_inline_entries = data->GetTargetInlineEntries();
  ASSERT_EQ(target_inline_entries.size(), 0U);

  const auto& overlay_entries = data->GetOverlayEntries();
  ASSERT_EQ(overlay_entries.size(), 1U);
  ASSERT_OVERLAY_ENTRY(overlay_entries[0], R::overlay::string::str3, R::target::string::str3);
}

TEST(IdmapTests, CreateIdmapDataInlineResources) {
  auto idmap_data = TestIdmapDataFromApkAssets("/target/target.apk", "/overlay/overlay.apk",
                                               "Inline", PolicyFlags::PUBLIC,
                                               /* enforce_overlayable */ false);

  ASSERT_TRUE(idmap_data) << idmap_data.GetErrorMessage();
  auto& data = *idmap_data;

  const auto& target_entries = data->GetTargetEntries();
  ASSERT_EQ(target_entries.size(), 0U);

  constexpr size_t overlay_string_pool_size = 10U;
  const auto& target_inline_entries = data->GetTargetInlineEntries();
  ASSERT_EQ(target_inline_entries.size(), 2U);
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[0], R::target::integer::int1, std::string(),
                             Res_value::TYPE_INT_DEC, 73U);  // -> 73
  ASSERT_TARGET_INLINE_ENTRY(target_inline_entries[1], R::target::string::str1, std::string(),
                             Res_value::TYPE_STRING,
                             overlay_string_pool_size + 0U);  // -> "Hello World"

  const auto& overlay_entries = data->GetOverlayEntries();
  ASSERT_EQ(overlay_entries.size(), 0U);
}

TEST(IdmapTests, IdmapHeaderIsUpToDate) {
  fclose(stderr);  // silence expected warnings from libandroidfw

  const std::string target_apk_path {kIdmapRawTargetPath};
  const std::string overlay_apk_path {kIdmapRawOverlayPath};
  const std::string overlay_name {kIdmapRawOverlayName};
  const PolicyBitmask policies = kIdmapRawDataPolicies;
  const uint32_t target_crc = kIdmapRawDataTargetCrc;
  const uint32_t overlay_crc = kIdmapRawOverlayCrc;

  std::string raw(reinterpret_cast<const char*>(kIdmapRawData), kIdmapRawDataLen);
  std::istringstream raw_stream(raw);

  auto result = Idmap::FromBinaryStream(raw_stream);
  ASSERT_TRUE(result);
  const auto idmap = std::move(*result);

  std::stringstream stream;
  BinaryStreamVisitor visitor(stream);
  idmap->accept(&visitor);

  std::unique_ptr<const IdmapHeader> header = IdmapHeader::FromBinaryStream(stream);
  ASSERT_THAT(header, NotNull());
  ASSERT_TRUE(header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                 kIdmapRawDataTargetCrc, overlay_crc, policies,
                                 /* enforce_overlayable */ true));

  // magic: bytes (0x0, 0x03)
  std::string bad_magic_string(stream.str());
  bad_magic_string[0x0] = '.';
  bad_magic_string[0x1] = '.';
  bad_magic_string[0x2] = '.';
  bad_magic_string[0x3] = '.';
  std::stringstream bad_magic_stream(bad_magic_string);
  std::unique_ptr<const IdmapHeader> bad_magic_header =
      IdmapHeader::FromBinaryStream(bad_magic_stream);
  ASSERT_EQ(nullptr, bad_magic_header);

  // version: bytes (0x4, 0x07)
  std::string bad_version_string(stream.str());
  bad_version_string[0x4] = '.';
  bad_version_string[0x5] = '.';
  bad_version_string[0x6] = '.';
  bad_version_string[0x7] = '.';
  std::stringstream bad_version_stream(bad_version_string);
  std::unique_ptr<const IdmapHeader> bad_version_header =
      IdmapHeader::FromBinaryStream(bad_version_stream);
  ASSERT_EQ(nullptr, bad_version_header);

  // target crc: bytes (0x8, 0xb)
  std::string bad_target_crc_string(stream.str());
  bad_target_crc_string[0x8] = '.';
  bad_target_crc_string[0x9] = '.';
  bad_target_crc_string[0xa] = '.';
  bad_target_crc_string[0xb] = '.';
  std::stringstream bad_target_crc_stream(bad_target_crc_string);
  std::unique_ptr<const IdmapHeader> bad_target_crc_header =
      IdmapHeader::FromBinaryStream(bad_target_crc_stream);
  ASSERT_THAT(bad_target_crc_header, NotNull());
  ASSERT_NE(header->GetTargetCrc(), bad_target_crc_header->GetTargetCrc());
  ASSERT_FALSE(bad_target_crc_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                                 target_crc, overlay_crc, policies,
                                                 /* enforce_overlayable */ true));

  // overlay crc: bytes (0xc, 0xf)
  std::string bad_overlay_crc_string(stream.str());
  bad_overlay_crc_string[0xc] = '.';
  bad_overlay_crc_string[0xd] = '.';
  bad_overlay_crc_string[0xe] = '.';
  bad_overlay_crc_string[0xf] = '.';
  std::stringstream bad_overlay_crc_stream(bad_overlay_crc_string);
  std::unique_ptr<const IdmapHeader> bad_overlay_crc_header =
      IdmapHeader::FromBinaryStream(bad_overlay_crc_stream);
  ASSERT_THAT(bad_overlay_crc_header, NotNull());
  ASSERT_NE(header->GetOverlayCrc(), bad_overlay_crc_header->GetOverlayCrc());
  ASSERT_FALSE(bad_overlay_crc_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                                  target_crc, overlay_crc, policies,
                                                  /* enforce_overlayable */ true));

  // fulfilled policy: bytes (0x10, 0x13)
  std::string bad_policy_string(stream.str());
  bad_policy_string[0x10] = '.';
  bad_policy_string[0x11] = '.';
  bad_policy_string[0x12] = '.';
  bad_policy_string[0x13] = '.';
  std::stringstream bad_policy_stream(bad_policy_string);
  std::unique_ptr<const IdmapHeader> bad_policy_header =
      IdmapHeader::FromBinaryStream(bad_policy_stream);
  ASSERT_THAT(bad_policy_header, NotNull());
  ASSERT_NE(header->GetFulfilledPolicies(), bad_policy_header->GetFulfilledPolicies());
  ASSERT_FALSE(bad_policy_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                             target_crc, overlay_crc, policies,
                                             /* enforce_overlayable */ true));

  // enforce overlayable: bytes (0x14)
  std::string bad_enforce_string(stream.str());
  bad_enforce_string[0x14] = '\0';
  std::stringstream bad_enforce_stream(bad_enforce_string);
  std::unique_ptr<const IdmapHeader> bad_enforce_header =
      IdmapHeader::FromBinaryStream(bad_enforce_stream);
  ASSERT_THAT(bad_enforce_header, NotNull());
  ASSERT_NE(header->GetEnforceOverlayable(), bad_enforce_header->GetEnforceOverlayable());
  ASSERT_FALSE(bad_enforce_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                              target_crc, overlay_crc, policies,
                                              /* enforce_overlayable */ true));

  // target path: bytes (0x1c, 0x27)
  std::string bad_target_path_string(stream.str());
  bad_target_path_string[0x1c] = '\0';
  std::stringstream bad_target_path_stream(bad_target_path_string);
  std::unique_ptr<const IdmapHeader> bad_target_path_header =
      IdmapHeader::FromBinaryStream(bad_target_path_stream);
  ASSERT_THAT(bad_target_path_header, NotNull());
  ASSERT_NE(header->GetTargetPath(), bad_target_path_header->GetTargetPath());
  ASSERT_FALSE(bad_target_path_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                                  target_crc, overlay_crc, policies,
                                                  /* enforce_overlayable */ true));

  // overlay path: bytes (0x2c, 0x37)
  std::string bad_overlay_path_string(stream.str());
  bad_overlay_path_string[0x33] = '\0';
  std::stringstream bad_overlay_path_stream(bad_overlay_path_string);
  std::unique_ptr<const IdmapHeader> bad_overlay_path_header =
      IdmapHeader::FromBinaryStream(bad_overlay_path_stream);
  ASSERT_THAT(bad_overlay_path_header, NotNull());
  ASSERT_NE(header->GetOverlayPath(), bad_overlay_path_header->GetOverlayPath());
  ASSERT_FALSE(bad_overlay_path_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                                   target_crc, overlay_crc, policies,
                                                   /* enforce_overlayable */ true));

  // overlay name: bytes (0x3c, 0x47)
  std::string bad_overlay_name_string(stream.str());
  bad_overlay_name_string[0x3c] = '\0';
  std::stringstream bad_overlay_name_stream(bad_overlay_name_string);
  std::unique_ptr<const IdmapHeader> bad_overlay_name_header =
      IdmapHeader::FromBinaryStream(bad_overlay_name_stream);
  ASSERT_THAT(bad_overlay_name_header, NotNull());
  ASSERT_NE(header->GetOverlayName(), bad_overlay_name_header->GetOverlayName());
  ASSERT_FALSE(bad_overlay_name_header->IsUpToDate(target_apk_path, overlay_apk_path, overlay_name,
                                                   target_crc, overlay_crc, policies,
                                                   /* enforce_overlayable */ true));
}

class TestVisitor : public Visitor {
 public:
  explicit TestVisitor(std::ostream& stream) : stream_(stream) {
  }

  void visit(const Idmap& idmap ATTRIBUTE_UNUSED) override {
    stream_ << "TestVisitor::visit(Idmap)" << '\n';
  }

  void visit(const IdmapHeader& idmap ATTRIBUTE_UNUSED) override {
    stream_ << "TestVisitor::visit(IdmapHeader)" << '\n';
  }

  void visit(const IdmapConstraints& idmap ATTRIBUTE_UNUSED) override {
    stream_ << "TestVisitor::visit(IdmapConstraints)" << '\n';
  }

  void visit(const IdmapData& idmap ATTRIBUTE_UNUSED) override {
    stream_ << "TestVisitor::visit(IdmapData)" << '\n';
  }

  void visit(const IdmapData::Header& idmap ATTRIBUTE_UNUSED) override {
    stream_ << "TestVisitor::visit(IdmapData::Header)" << '\n';
  }

 private:
  std::ostream& stream_;
};

TEST(IdmapTests, TestVisitor) {
  std::string raw(reinterpret_cast<const char*>(kIdmapRawData), kIdmapRawDataLen);
  std::istringstream stream(raw);

  const auto idmap = Idmap::FromBinaryStream(stream);
  ASSERT_TRUE(idmap);

  std::stringstream test_stream;
  TestVisitor visitor(test_stream);
  (*idmap)->accept(&visitor);

  ASSERT_EQ(test_stream.str(),
            "TestVisitor::visit(IdmapHeader)\n"
            "TestVisitor::visit(IdmapConstraints)\n"
            "TestVisitor::visit(Idmap)\n"
            "TestVisitor::visit(IdmapData::Header)\n"
            "TestVisitor::visit(IdmapData)\n");
}

}  // namespace android::idmap2
