/*
 * Copyright (C) 2021 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 <gtest/gtest.h>
#include <idmap2/FabricatedOverlay.h>
#include "TestHelpers.h"

#include <fstream>
#include <utility>

namespace android::idmap2 {

TEST(FabricatedOverlayTests, OverlayInfo) {
  auto overlay =
      FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
          .SetOverlayable("TestResources")
          .Build();

  ASSERT_TRUE(overlay);
  auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
  auto info = container->FindOverlayInfo("SandTheme");
  ASSERT_TRUE(info);
  EXPECT_EQ("SandTheme", (*info).name);
  EXPECT_EQ("TestResources", (*info).target_name);

  info = container->FindOverlayInfo("OceanTheme");
  ASSERT_FALSE(info);
}

TEST(FabricatedOverlayTests, SetResourceValue) {
  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 overlay =
      FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
          .SetResourceValue(
              "com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "port")
          .SetResourceValue(
              "com.example.target.split:integer/int2", Res_value::TYPE_INT_DEC, 2U, "land")
          .SetResourceValue(
              "string/int3", Res_value::TYPE_REFERENCE, 0x7f010000, "xxhdpi-v7")
          .SetResourceValue(
              "com.example.target:string/string1",
              Res_value::TYPE_STRING,
              "foobar",
              "en-rUS-normal-xxhdpi-v21")
          .SetResourceValue("com.example.target:drawable/dr1", fd, "port-xxhdpi-v7")
          .setFrroPath("/foo/bar/biz.frro")
          .Build();
  ASSERT_TRUE(overlay);
  auto container = FabricatedOverlayContainer::FromOverlay(std::move(*overlay));
  auto info = container->FindOverlayInfo("SandTheme");
  ASSERT_TRUE(info);
  ASSERT_TRUE((*info).target_name.empty());

  auto crc = (*container).GetCrc();
  ASSERT_TRUE(crc) << crc.GetErrorMessage();
  EXPECT_NE(0U, *crc);

  auto pairs = container->GetOverlayData(*info);
  ASSERT_TRUE(pairs);
  ASSERT_EQ(5U, pairs->pairs.size());
  auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
                                        pairs->string_pool_data->data_length, false);

  auto& it = pairs->pairs[0];
  ASSERT_EQ("com.example.target:drawable/dr1", it.resource_name);
  auto entry = std::get_if<TargetValueWithConfig>(&it.value);
  ASSERT_NE(nullptr, entry);
  ASSERT_EQ(std::string("frro://foo/bar/biz.frro?offset=16&size=8341"),
      string_pool.string8At(entry->value.data_value).value_or(""));
  ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
  ASSERT_EQ("port-xxhdpi-v7", entry->config);

  it = pairs->pairs[1];
  ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
  entry = std::get_if<TargetValueWithConfig>(&it.value);
  ASSERT_NE(nullptr, entry);
  ASSERT_EQ(1U, entry->value.data_value);
  ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
  ASSERT_EQ("port", entry->config);

  it = pairs->pairs[2];
  ASSERT_EQ("com.example.target:string/int3", it.resource_name);
  entry = std::get_if<TargetValueWithConfig>(&it.value);
  ASSERT_NE(nullptr, entry);
  ASSERT_EQ(0x7f010000, entry->value.data_value);
  ASSERT_EQ(Res_value::TYPE_REFERENCE, entry->value.data_type);
  ASSERT_EQ("xxhdpi-v7", entry->config);

  it = pairs->pairs[3];
  ASSERT_EQ("com.example.target:string/string1", it.resource_name);
  entry = std::get_if<TargetValueWithConfig>(&it.value);
  ASSERT_NE(nullptr, entry);
  ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
  ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
  ASSERT_EQ("en-rUS-normal-xxhdpi-v21", entry->config);

  it = pairs->pairs[4];
  ASSERT_EQ("com.example.target.split:integer/int2", it.resource_name);
  entry = std::get_if<TargetValueWithConfig>(&it.value);
  ASSERT_NE(nullptr, entry);
  ASSERT_EQ(2U, entry->value.data_value);
  ASSERT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);
  ASSERT_EQ("land", entry->config);
}

TEST(FabricatedOverlayTests, SetResourceValueBadArgs) {
  {
    auto builder =
        FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
            .SetResourceValue("int1", Res_value::TYPE_INT_DEC, 1U, "");
    ASSERT_FALSE(builder.Build());
  }
  {
    auto builder =
        FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
            .SetResourceValue("com.example.target:int2", Res_value::TYPE_INT_DEC, 1U, "");
    ASSERT_FALSE(builder.Build());
  }
}

TEST(FabricatedOverlayTests, SerializeAndDeserialize) {
  auto overlay =
      FabricatedOverlay::Builder("com.example.overlay", "SandTheme", "com.example.target")
          .SetOverlayable("TestResources")
          .SetResourceValue("com.example.target:integer/int1", Res_value::TYPE_INT_DEC, 1U, "")
          .SetResourceValue(
              "com.example.target:string/string1", Res_value::TYPE_STRING, "foobar", "")
          .Build();
  ASSERT_TRUE(overlay);
  TemporaryFile tf;
  std::ofstream out(tf.path);
  ASSERT_TRUE((*overlay).ToBinaryStream(out));
  out.close();

  auto container = OverlayResourceContainer::FromPath(tf.path);
  ASSERT_TRUE(container) << container.GetErrorMessage();
  EXPECT_EQ(tf.path, (*container)->GetPath());

  auto crc = (*container)->GetCrc();
  ASSERT_TRUE(crc) << crc.GetErrorMessage();
  EXPECT_NE(0U, *crc);

  auto info = (*container)->FindOverlayInfo("SandTheme");
  ASSERT_TRUE(info) << info.GetErrorMessage();
  EXPECT_EQ("SandTheme", (*info).name);
  EXPECT_EQ("TestResources", (*info).target_name);

  auto pairs = (*container)->GetOverlayData(*info);
  ASSERT_TRUE(pairs) << pairs.GetErrorMessage();
  EXPECT_EQ(2U, pairs->pairs.size());
  auto string_pool = ResStringPool(pairs->string_pool_data->data.get(),
                                        pairs->string_pool_data->data_length, false);

  auto& it = pairs->pairs[0];
  ASSERT_EQ("com.example.target:integer/int1", it.resource_name);
  auto entry = std::get_if<TargetValueWithConfig>(&it.value);
  ASSERT_NE(nullptr, entry);
  EXPECT_EQ(1U, entry->value.data_value);
  EXPECT_EQ(Res_value::TYPE_INT_DEC, entry->value.data_type);

  it = pairs->pairs[1];
  ASSERT_EQ("com.example.target:string/string1", it.resource_name);
  entry = std::get_if<TargetValueWithConfig>(&it.value);
  ASSERT_NE(nullptr, entry);
  ASSERT_EQ(Res_value::TYPE_STRING, entry->value.data_type);
  ASSERT_EQ(std::string("foobar"), string_pool.string8At(entry->value.data_value).value_or(""));
}

}  // namespace android::idmap2
