/*
 * 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(), 0x09U);
  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, 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(), 0x09U);
  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 idmap_result = Idmap::FromContainers(
      **target, **overlay, TestConstants::OVERLAY_NAME_ALL_POLICIES, PolicyFlags::PUBLIC,
      /* enforce_overlayable */ true);
  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(), 0x09U);
  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, 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 idmap_result = Idmap::FromContainers(
      **target, **overlay, TestConstants::OVERLAY_NAME_DEFAULT, PolicyFlags::PUBLIC,
      /* enforce_overlayable */ true);
  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);
  TemporaryFile tf;
  std::ofstream out(tf.path);
  ASSERT_TRUE((*frro).ToBinaryStream(out));
  out.close();

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

  auto idmap_result = Idmap::FromContainers(**target, **overlay, "SandTheme", PolicyFlags::PUBLIC,
                                            /* enforce_overlayable */ true);
  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 idmap_result = Idmap::FromContainers(**target, **overlay, "", PolicyFlags::PUBLIC,
                                              /* enforce_overlayable */ true);
    ASSERT_FALSE(idmap_result);
  }
  {
    auto idmap_result = Idmap::FromContainers(**target, **overlay, "unknown", PolicyFlags::PUBLIC,
                                              /* enforce_overlayable */ true);
    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 idmap_result = Idmap::FromContainers(
      **target, **overlay, TestConstants::OVERLAY_NAME_DEFAULT, PolicyFlags::PUBLIC,
      /* enforce_overlayable */ true);
  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 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(Idmap)\n"
            "TestVisitor::visit(IdmapData::Header)\n"
            "TestVisitor::visit(IdmapData)\n");
}

}  // namespace android::idmap2
