/*
 * Copyright (C) 2017 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 "configuration/ConfigurationParser.h"

#include <string>

#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"

#include "SdkConstants.h"
#include "configuration/ConfigurationParser.internal.h"
#include "test/Test.h"
#include "xml/XmlDom.h"

using ::android::ConfigDescription;

namespace aapt {

namespace configuration {

bool operator==(const ConfiguredArtifact& lhs, const ConfiguredArtifact& rhs) {
  return lhs.name == rhs.name && lhs.abi_group == rhs.abi_group &&
         lhs.screen_density_group == rhs.screen_density_group &&
         lhs.locale_group == rhs.locale_group && lhs.android_sdk == rhs.android_sdk &&
         lhs.device_feature_group == rhs.device_feature_group &&
         lhs.gl_texture_group == rhs.gl_texture_group;
}

namespace handler {

namespace {

using ::aapt::configuration::Abi;
using ::aapt::configuration::AndroidManifest;
using ::aapt::configuration::AndroidSdk;
using ::aapt::configuration::ConfiguredArtifact;
using ::aapt::configuration::DeviceFeature;
using ::aapt::configuration::ExtractConfiguration;
using ::aapt::configuration::GlTexture;
using ::aapt::configuration::Locale;
using ::aapt::configuration::PostProcessingConfiguration;
using ::aapt::xml::Element;
using ::aapt::xml::NodeCast;
using ::android::ResTable_config;
using ::android::base::StringPrintf;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::SizeIs;
using ::testing::StrEq;

constexpr const char* kValidConfig = R"(<?xml version="1.0" encoding="utf-8" ?>
<post-process xmlns="http://schemas.android.com/tools/aapt">
  <abi-groups>
    <abi-group label="other" version-code-order="2">
      <abi>x86</abi>
      <abi>mips</abi>
    </abi-group>
    <abi-group label="arm" version-code-order="1">
      <abi>armeabi-v7a</abi>
      <abi>arm64-v8a</abi>
    </abi-group>
  </abi-groups>
  <screen-density-groups>
    <screen-density-group label="large" version-code-order="2">
      <screen-density>xhdpi</screen-density>
      <screen-density>xxhdpi</screen-density>
      <screen-density>xxxhdpi</screen-density>
    </screen-density-group>
    <screen-density-group label="alldpi" version-code-order="1">
      <screen-density>ldpi</screen-density>
      <screen-density>mdpi</screen-density>
      <screen-density>hdpi</screen-density>
      <screen-density>xhdpi</screen-density>
      <screen-density>xxhdpi</screen-density>
      <screen-density>xxxhdpi</screen-density>
    </screen-density-group>
  </screen-density-groups>
  <locale-groups>
    <locale-group label="europe" version-code-order="1">
      <locale>en</locale>
      <locale>es</locale>
      <locale>fr</locale>
      <locale>de</locale>
    </locale-group>
    <locale-group label="north-america" version-code-order="2">
      <locale>en</locale>
      <locale>es-rMX</locale>
      <locale>fr-rCA</locale>
    </locale-group>
    <locale-group label="all" version-code-order="-1">
      <locale />
    </locale-group>
  </locale-groups>
  <android-sdks>
    <android-sdk
    	  label="v19"
        minSdkVersion="19"
        targetSdkVersion="24"
        maxSdkVersion="25">
      <manifest>
        <!--- manifest additions here XSLT? TODO -->
      </manifest>
    </android-sdk>
  </android-sdks>
  <gl-texture-groups>
    <gl-texture-group label="dxt1" version-code-order="2">
      <gl-texture name="GL_EXT_texture_compression_dxt1">
        <texture-path>assets/dxt1/*</texture-path>
      </gl-texture>
    </gl-texture-group>
  </gl-texture-groups>
  <device-feature-groups>
    <device-feature-group label="low-latency" version-code-order="2">
      <supports-feature>android.hardware.audio.low_latency</supports-feature>
    </device-feature-group>
  </device-feature-groups>
  <artifacts>
    <artifact-format>
      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
    </artifact-format>
    <artifact
        name="art1"
        abi-group="arm"
        screen-density-group="large"
        locale-group="europe"
        android-sdk="v19"
        gl-texture-group="dxt1"
        device-feature-group="low-latency"/>
    <artifact
        name="art2"
        abi-group="other"
        screen-density-group="alldpi"
        locale-group="north-america"
        android-sdk="v19"
        gl-texture-group="dxt1"
        device-feature-group="low-latency"/>
  </artifacts>
</post-process>
)";

class ConfigurationParserTest : public ConfigurationParser, public ::testing::Test {
 public:
  ConfigurationParserTest() : ConfigurationParser("", "config.xml") {
  }

 protected:
  StdErrDiagnostics diag_;
};

TEST_F(ConfigurationParserTest, ForPath_NoFile) {
  auto result = ConfigurationParser::ForPath("./does_not_exist.xml");
  EXPECT_FALSE(result);
}

TEST_F(ConfigurationParserTest, ExtractConfiguration) {
  std::optional<PostProcessingConfiguration> maybe_config =
      ExtractConfiguration(kValidConfig, "fake.xml", &diag_);

  PostProcessingConfiguration config = maybe_config.value();

  auto& arm = config.abi_groups["arm"];
  auto& other = config.abi_groups["other"];
  EXPECT_EQ(arm.order, 1);
  EXPECT_EQ(other.order, 2);

  auto& large = config.screen_density_groups["large"];
  auto& alldpi = config.screen_density_groups["alldpi"];
  EXPECT_EQ(large.order, 2);
  EXPECT_EQ(alldpi.order, 1);

  auto& north_america = config.locale_groups["north-america"];
  auto& europe = config.locale_groups["europe"];
  auto& all = config.locale_groups["all"];
  // Checked in reverse to make sure access order does not matter.
  EXPECT_EQ(north_america.order, 2);
  EXPECT_EQ(europe.order, 1);
  EXPECT_EQ(all.order, -1);
  EXPECT_EQ(3ul, config.locale_groups.size());
}

TEST_F(ConfigurationParserTest, ValidateFile) {
  auto parser = ConfigurationParser::ForContents(kValidConfig, "conf.xml").WithDiagnostics(&diag_);
  auto result = parser.Parse("test.apk");
  ASSERT_TRUE(result);
  const std::vector<OutputArtifact>& value = result.value();
  EXPECT_THAT(value, SizeIs(2ul));

  const OutputArtifact& a1 = value[0];
  EXPECT_EQ(a1.name, "art1.apk");
  EXPECT_EQ(a1.version, 1);
  EXPECT_THAT(a1.abis, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
  EXPECT_THAT(a1.screen_densities,
              ElementsAre(test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
                          test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
                          test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
  EXPECT_THAT(a1.locales, ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es"),
                                      test::ParseConfigOrDie("fr"), test::ParseConfigOrDie("de")));
  ASSERT_TRUE(a1.android_sdk);
  ASSERT_TRUE(a1.android_sdk.value().min_sdk_version);
  EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19L);
  EXPECT_THAT(a1.textures, SizeIs(1ul));
  EXPECT_THAT(a1.features, SizeIs(1ul));

  const OutputArtifact& a2 = value[1];
  EXPECT_EQ(a2.name, "art2.apk");
  EXPECT_EQ(a2.version, 2);
  EXPECT_THAT(a2.abis, ElementsAre(Abi::kX86, Abi::kMips));
  EXPECT_THAT(a2.screen_densities,
              ElementsAre(test::ParseConfigOrDie("ldpi").CopyWithoutSdkVersion(),
                          test::ParseConfigOrDie("mdpi").CopyWithoutSdkVersion(),
                          test::ParseConfigOrDie("hdpi").CopyWithoutSdkVersion(),
                          test::ParseConfigOrDie("xhdpi").CopyWithoutSdkVersion(),
                          test::ParseConfigOrDie("xxhdpi").CopyWithoutSdkVersion(),
                          test::ParseConfigOrDie("xxxhdpi").CopyWithoutSdkVersion()));
  EXPECT_THAT(a2.locales,
              ElementsAre(test::ParseConfigOrDie("en"), test::ParseConfigOrDie("es-rMX"),
                          test::ParseConfigOrDie("fr-rCA")));
  ASSERT_TRUE(a2.android_sdk);
  ASSERT_TRUE(a2.android_sdk.value().min_sdk_version);
  EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19L);
  EXPECT_THAT(a2.textures, SizeIs(1ul));
  EXPECT_THAT(a2.features, SizeIs(1ul));
}

TEST_F(ConfigurationParserTest, ConfiguredArtifactOrdering) {
  // Create a base builder with the configuration groups but no artifacts to allow it to be copied.
  test::PostProcessingConfigurationBuilder base_builder = test::PostProcessingConfigurationBuilder()
                                                              .AddAbiGroup("arm")
                                                              .AddAbiGroup("arm64")
                                                              .AddAndroidSdk("v23", 23)
                                                              .AddAndroidSdk("v19", 19);

  {
    // Test version ordering.
    ConfiguredArtifact v23;
    v23.android_sdk = {"v23"};
    ConfiguredArtifact v19;
    v19.android_sdk = {"v19"};

    test::PostProcessingConfigurationBuilder builder = base_builder;
    PostProcessingConfiguration config = builder.AddArtifact(v23).AddArtifact(v19).Build();

    config.SortArtifacts();
    ASSERT_THAT(config.artifacts, SizeIs(2));
    EXPECT_THAT(config.artifacts[0], Eq(v19));
    EXPECT_THAT(config.artifacts[1], Eq(v23));
  }

  {
    // Test ABI ordering.
    ConfiguredArtifact arm;
    arm.android_sdk = {"v19"};
    arm.abi_group = {"arm"};
    ConfiguredArtifact arm64;
    arm64.android_sdk = {"v19"};
    arm64.abi_group = {"arm64"};

    test::PostProcessingConfigurationBuilder builder = base_builder;
    PostProcessingConfiguration config = builder.AddArtifact(arm64).AddArtifact(arm).Build();

    config.SortArtifacts();
    ASSERT_THAT(config.artifacts, SizeIs(2));
    EXPECT_THAT(config.artifacts[0], Eq(arm));
    EXPECT_THAT(config.artifacts[1], Eq(arm64));
  }

  {
    // Test Android SDK has precedence over ABI.
    ConfiguredArtifact arm;
    arm.android_sdk = {"v23"};
    arm.abi_group = {"arm"};
    ConfiguredArtifact arm64;
    arm64.android_sdk = {"v19"};
    arm64.abi_group = {"arm64"};

    test::PostProcessingConfigurationBuilder builder = base_builder;
    PostProcessingConfiguration config = builder.AddArtifact(arm64).AddArtifact(arm).Build();

    config.SortArtifacts();
    ASSERT_THAT(config.artifacts, SizeIs(2));
    EXPECT_THAT(config.artifacts[0], Eq(arm64));
    EXPECT_THAT(config.artifacts[1], Eq(arm));
  }

  {
    // Test version is better than ABI.
    ConfiguredArtifact arm;
    arm.abi_group = {"arm"};
    ConfiguredArtifact v19;
    v19.android_sdk = {"v19"};

    test::PostProcessingConfigurationBuilder builder = base_builder;
    PostProcessingConfiguration config = builder.AddArtifact(v19).AddArtifact(arm).Build();

    config.SortArtifacts();
    ASSERT_THAT(config.artifacts, SizeIs(2));
    EXPECT_THAT(config.artifacts[0], Eq(arm));
    EXPECT_THAT(config.artifacts[1], Eq(v19));
  }

  {
    // Test version is sorted higher than no version.
    ConfiguredArtifact arm;
    arm.abi_group = {"arm"};
    ConfiguredArtifact v19;
    v19.abi_group = {"arm"};
    v19.android_sdk = {"v19"};

    test::PostProcessingConfigurationBuilder builder = base_builder;
    PostProcessingConfiguration config = builder.AddArtifact(v19).AddArtifact(arm).Build();

    config.SortArtifacts();
    ASSERT_THAT(config.artifacts, SizeIs(2));
    EXPECT_THAT(config.artifacts[0], Eq(arm));
    EXPECT_THAT(config.artifacts[1], Eq(v19));
  }
}

TEST_F(ConfigurationParserTest, InvalidNamespace) {
  constexpr const char* invalid_ns = R"(<?xml version="1.0" encoding="utf-8" ?>
    <post-process xmlns="http://schemas.android.com/tools/another-unknown-tool" />)";

  auto result = ConfigurationParser::ForContents(invalid_ns, "config.xml").Parse("test.apk");
  ASSERT_FALSE(result);
}

TEST_F(ConfigurationParserTest, ArtifactAction) {
  PostProcessingConfiguration config;
  const auto doc = test::BuildXmlDom(R"xml(
      <artifact
          abi-group="arm"
          screen-density-group="large"
          locale-group="europe"
          android-sdk="v19"
          gl-texture-group="dxt1"
          device-feature-group="low-latency"/>)xml");

  ASSERT_TRUE(ArtifactTagHandler(&config, NodeCast<Element>(doc->root.get()), &diag_));

  EXPECT_THAT(config.artifacts, SizeIs(1ul));

  auto& artifact = config.artifacts.back();
  EXPECT_FALSE(artifact.name);  // TODO: make this fail.
  EXPECT_EQ("arm", artifact.abi_group.value());
  EXPECT_EQ("large", artifact.screen_density_group.value());
  EXPECT_EQ("europe", artifact.locale_group.value());
  EXPECT_EQ("v19", artifact.android_sdk.value());
  EXPECT_EQ("dxt1", artifact.gl_texture_group.value());
  EXPECT_EQ("low-latency", artifact.device_feature_group.value());
}

TEST_F(ConfigurationParserTest, ArtifactFormatAction) {
  const auto doc = test::BuildXmlDom(R"xml(
    <artifact-format>
      ${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release
    </artifact-format>)xml");

  PostProcessingConfiguration config;
  bool ok = ArtifactFormatTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);
  ASSERT_TRUE(config.artifact_format);
  EXPECT_EQ(
      "${base}.${abi}.${screen-density}.${locale}.${sdk}.${gl}.${feature}.release",
      static_cast<std::string>(config.artifact_format.value())
  );
}

TEST_F(ConfigurationParserTest, AbiGroupAction) {
  static constexpr const char* xml = R"xml(
    <abi-group label="arm"  version-code-order="2">
      <!-- First comment. -->
      <abi>
        armeabi-v7a
      </abi>
      <!-- Another comment. -->
      <abi>arm64-v8a</abi>
    </abi-group>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  EXPECT_THAT(config.abi_groups, SizeIs(1ul));
  ASSERT_EQ(1u, config.abi_groups.count("arm"));

  auto& out = config.abi_groups["arm"].entry;
  ASSERT_THAT(out, ElementsAre(Abi::kArmV7a, Abi::kArm64V8a));
}

TEST_F(ConfigurationParserTest, AbiGroupAction_EmptyGroup) {
  static constexpr const char* xml =
      R"xml(<abi-group label="arm64-v8a" version-code-order="3"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  EXPECT_THAT(config.abi_groups, SizeIs(1ul));
  ASSERT_EQ(1u, config.abi_groups.count("arm64-v8a"));

  auto& out = config.abi_groups["arm64-v8a"];
  ASSERT_THAT(out.entry, ElementsAre(Abi::kArm64V8a));
  EXPECT_EQ(3, out.order);
}

TEST_F(ConfigurationParserTest, AbiGroupAction_EmptyGroup_NoOrder) {
  static constexpr const char* xml = R"xml(<abi-group label="arm64-v8a"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, AbiGroupAction_InvalidEmptyGroup) {
  static constexpr const char* xml = R"xml(<abi-group label="arm" order="2"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = AbiGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, ScreenDensityGroupAction) {
  static constexpr const char* xml = R"xml(
    <screen-density-group label="large" version-code-order="2">
      <screen-density>xhdpi</screen-density>
      <screen-density>
        xxhdpi
      </screen-density>
      <screen-density>xxxhdpi</screen-density>
    </screen-density-group>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  EXPECT_THAT(config.screen_density_groups, SizeIs(1ul));
  ASSERT_EQ(1u, config.screen_density_groups.count("large"));

  ConfigDescription xhdpi;
  xhdpi.density = ResTable_config::DENSITY_XHIGH;
  ConfigDescription xxhdpi;
  xxhdpi.density = ResTable_config::DENSITY_XXHIGH;
  ConfigDescription xxxhdpi;
  xxxhdpi.density = ResTable_config::DENSITY_XXXHIGH;

  auto& out = config.screen_density_groups["large"].entry;
  ASSERT_THAT(out, ElementsAre(xhdpi, xxhdpi, xxxhdpi));
}

TEST_F(ConfigurationParserTest, ScreenDensityGroupAction_EmtpyGroup) {
  static constexpr const char* xml =
      R"xml(<screen-density-group label="xhdpi" version-code-order="4"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  EXPECT_THAT(config.screen_density_groups, SizeIs(1ul));
  ASSERT_EQ(1u, config.screen_density_groups.count("xhdpi"));

  ConfigDescription xhdpi;
  xhdpi.density = ResTable_config::DENSITY_XHIGH;

  auto& out = config.screen_density_groups["xhdpi"];
  EXPECT_THAT(out.entry, ElementsAre(xhdpi));
  EXPECT_EQ(4, out.order);
}

TEST_F(ConfigurationParserTest, ScreenDensityGroupAction_EmtpyGroup_NoVersion) {
  static constexpr const char* xml = R"xml(<screen-density-group label="xhdpi"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, ScreenDensityGroupAction_InvalidEmtpyGroup) {
  static constexpr const char* xml = R"xml(<screen-density-group label="really-big-screen"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = ScreenDensityGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, LocaleGroupAction) {
  static constexpr const char* xml = R"xml(
    <locale-group label="europe" version-code-order="2">
      <locale>en</locale>
      <locale>es</locale>
      <locale>fr</locale>
      <locale>de</locale>
    </locale-group>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  ASSERT_EQ(1ul, config.locale_groups.size());
  ASSERT_EQ(1u, config.locale_groups.count("europe"));

  const auto& out = config.locale_groups["europe"].entry;

  ConfigDescription en = test::ParseConfigOrDie("en");
  ConfigDescription es = test::ParseConfigOrDie("es");
  ConfigDescription fr = test::ParseConfigOrDie("fr");
  ConfigDescription de = test::ParseConfigOrDie("de");

  ASSERT_THAT(out, ElementsAre(en, es, fr, de));
}

TEST_F(ConfigurationParserTest, LocaleGroupAction_EmtpyGroup) {
  static constexpr const char* xml = R"xml(<locale-group label="en" version-code-order="6"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  ASSERT_EQ(1ul, config.locale_groups.size());
  ASSERT_EQ(1u, config.locale_groups.count("en"));

  const auto& out = config.locale_groups["en"];

  ConfigDescription en = test::ParseConfigOrDie("en");

  EXPECT_THAT(out.entry, ElementsAre(en));
  EXPECT_EQ(6, out.order);
}

TEST_F(ConfigurationParserTest, LocaleGroupAction_EmtpyGroup_NoOrder) {
  static constexpr const char* xml = R"xml(<locale-group label="en"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, LocaleGroupAction_InvalidEmtpyGroup) {
  static constexpr const char* xml = R"xml(<locale-group label="arm64"/>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = LocaleGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, AndroidSdkGroupAction) {
  static constexpr const char* xml = R"xml(
      <android-sdk label="v19"
          minSdkVersion="19"
          targetSdkVersion="24"
          maxSdkVersion="25">
        <manifest>
          <!--- manifest additions here XSLT? TODO -->
        </manifest>
      </android-sdk>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  ASSERT_EQ(1ul, config.android_sdks.size());
  ASSERT_EQ(1u, config.android_sdks.count("v19"));

  auto& out = config.android_sdks["v19"];

  AndroidSdk sdk;
  sdk.min_sdk_version = 19;
  sdk.target_sdk_version = 24;
  sdk.max_sdk_version = 25;
  sdk.manifest = AndroidManifest();

  ASSERT_EQ(sdk, out);
}

TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_SingleVersion) {
  {
    const char* xml = "<android-sdk label='v19' minSdkVersion='19'></android-sdk>";
    auto doc = test::BuildXmlDom(xml);

    PostProcessingConfiguration config;
    bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
    ASSERT_TRUE(ok);

    ASSERT_EQ(1ul, config.android_sdks.size());
    ASSERT_EQ(1u, config.android_sdks.count("v19"));

    auto& out = config.android_sdks["v19"];
    EXPECT_EQ(19, out.min_sdk_version);
    EXPECT_FALSE(out.max_sdk_version);
    EXPECT_FALSE(out.target_sdk_version);
  }

  {
    const char* xml =
        "<android-sdk label='v19' minSdkVersion='19' maxSdkVersion='19'></android-sdk>";
    auto doc = test::BuildXmlDom(xml);

    PostProcessingConfiguration config;
    bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
    ASSERT_TRUE(ok);

    ASSERT_EQ(1ul, config.android_sdks.size());
    ASSERT_EQ(1u, config.android_sdks.count("v19"));

    auto& out = config.android_sdks["v19"];
    EXPECT_EQ(19, out.max_sdk_version.value());
    EXPECT_EQ(19, out.min_sdk_version);
    EXPECT_FALSE(out.target_sdk_version);
  }

  {
    const char* xml =
        "<android-sdk label='v19' minSdkVersion='19' targetSdkVersion='19'></android-sdk>";
    auto doc = test::BuildXmlDom(xml);

    PostProcessingConfiguration config;
    bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
    ASSERT_TRUE(ok);

    ASSERT_EQ(1ul, config.android_sdks.size());
    ASSERT_EQ(1u, config.android_sdks.count("v19"));

    auto& out = config.android_sdks["v19"];
    EXPECT_EQ(19, out.target_sdk_version.value());
    EXPECT_EQ(19, out.min_sdk_version);
    EXPECT_FALSE(out.max_sdk_version);
  }
}

TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_InvalidVersion) {
  static constexpr const char* xml = R"xml(
    <android-sdk
        label="v19"
        minSdkVersion="v19"
        targetSdkVersion="v24"
        maxSdkVersion="v25">
      <manifest>
        <!--- manifest additions here XSLT? TODO -->
      </manifest>
    </android-sdk>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_FALSE(ok);
}

TEST_F(ConfigurationParserTest, AndroidSdkGroupAction_NonNumeric) {
  auto doc = test::BuildXmlDom(R"xml(
      <android-sdk
          label="Q"
          minSdkVersion="25"
          targetSdkVersion="Q"
          maxSdkVersion="Q">
      </android-sdk>)xml");

  PostProcessingConfiguration config;
  ASSERT_TRUE(AndroidSdkTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_));
  ASSERT_EQ(1ul, config.android_sdks.size());
  ASSERT_EQ(1u, config.android_sdks.count("Q"));

  AndroidSdk sdk;
  sdk.min_sdk_version = 25;
  sdk.target_sdk_version = 10000;
  sdk.max_sdk_version = 10000;
  ASSERT_EQ(sdk, config.android_sdks["Q"]);
}

TEST_F(ConfigurationParserTest, GlTextureGroupAction) {
  static constexpr const char* xml = R"xml(
    <gl-texture-group label="dxt1" version-code-order="2">
      <gl-texture name="GL_EXT_texture_compression_dxt1">
        <texture-path>assets/dxt1/main/*</texture-path>
        <texture-path>
          assets/dxt1/test/*
        </texture-path>
      </gl-texture>
    </gl-texture-group>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = GlTextureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  EXPECT_THAT(config.gl_texture_groups, SizeIs(1ul));
  ASSERT_EQ(1u, config.gl_texture_groups.count("dxt1"));

  auto& out = config.gl_texture_groups["dxt1"].entry;

  GlTexture texture{
      std::string("GL_EXT_texture_compression_dxt1"),
      {"assets/dxt1/main/*", "assets/dxt1/test/*"}
  };

  ASSERT_EQ(1ul, out.size());
  ASSERT_EQ(texture, out[0]);
}

TEST_F(ConfigurationParserTest, DeviceFeatureGroupAction) {
  static constexpr const char* xml = R"xml(
    <device-feature-group label="low-latency" version-code-order="2">
      <supports-feature>android.hardware.audio.low_latency</supports-feature>
      <supports-feature>
        android.hardware.audio.pro
      </supports-feature>
    </device-feature-group>)xml";

  auto doc = test::BuildXmlDom(xml);

  PostProcessingConfiguration config;
  bool ok = DeviceFeatureGroupTagHandler(&config, NodeCast<Element>(doc.get()->root.get()), &diag_);
  ASSERT_TRUE(ok);

  EXPECT_THAT(config.device_feature_groups, SizeIs(1ul));
  ASSERT_EQ(1u, config.device_feature_groups.count("low-latency"));

  auto& out = config.device_feature_groups["low-latency"].entry;

  DeviceFeature low_latency = "android.hardware.audio.low_latency";
  DeviceFeature pro = "android.hardware.audio.pro";
  ASSERT_THAT(out, ElementsAre(low_latency, pro));
}

TEST_F(ConfigurationParserTest, Group_Valid) {
  Group<int32_t> group;
  group["item1"].order = 1;
  group["item2"].order = 2;
  group["item3"].order = 3;
  group["item4"].order = 4;
  group["item5"].order = 5;
  group["item6"].order = 6;

  EXPECT_TRUE(IsGroupValid(group, "test", &diag_));
}

TEST_F(ConfigurationParserTest, Group_OverlappingOrder) {
  Group<int32_t> group;
  group["item1"].order = 1;
  group["item2"].order = 2;
  group["item3"].order = 3;
  group["item4"].order = 2;
  group["item5"].order = 5;
  group["item6"].order = 1;

  EXPECT_FALSE(IsGroupValid(group, "test", &diag_));
}

// Artifact name parser test cases.

TEST(ArtifactTest, Simple) {
  StdErrDiagnostics diag;
  ConfiguredArtifact x86;
  x86.abi_group = {"x86"};

  auto x86_result = x86.ToArtifactName("something.${abi}.apk", "", &diag);
  ASSERT_TRUE(x86_result);
  EXPECT_EQ(x86_result.value(), "something.x86.apk");

  ConfiguredArtifact arm;
  arm.abi_group = {"armeabi-v7a"};

  {
    auto arm_result = arm.ToArtifactName("app.${abi}.apk", "", &diag);
    ASSERT_TRUE(arm_result);
    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
  }

  {
    auto arm_result = arm.ToArtifactName("app.${abi}.apk", "different_name.apk", &diag);
    ASSERT_TRUE(arm_result);
    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
  }

  {
    auto arm_result = arm.ToArtifactName("${basename}.${abi}.apk", "app.apk", &diag);
    ASSERT_TRUE(arm_result);
    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
  }

  {
    auto arm_result = arm.ToArtifactName("app.${abi}.${ext}", "app.apk", &diag);
    ASSERT_TRUE(arm_result);
    EXPECT_EQ(arm_result.value(), "app.armeabi-v7a.apk");
  }
}

TEST(ArtifactTest, Complex) {
  StdErrDiagnostics diag;
  ConfiguredArtifact artifact;
  artifact.abi_group = {"mips64"};
  artifact.screen_density_group = {"ldpi"};
  artifact.device_feature_group = {"df1"};
  artifact.gl_texture_group = {"glx1"};
  artifact.locale_group = {"en-AU"};
  artifact.android_sdk = {"v26"};

  {
    auto result = artifact.ToArtifactName(
        "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "", &diag);
    ASSERT_TRUE(result);
    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
  }

  {
    auto result = artifact.ToArtifactName(
        "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
    ASSERT_TRUE(result);
    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
  }

  {
    auto result = artifact.ToArtifactName(
        "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.apk", "app.apk", &diag);
    ASSERT_TRUE(result);
    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
  }

  {
    auto result = artifact.ToArtifactName(
        "app.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}.${ext}", "app.apk", &diag);
    ASSERT_TRUE(result);
    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
  }

  {
    auto result = artifact.ToArtifactName(
        "${basename}.${density}_${locale}_${feature}_${gl}.${sdk}.${abi}", "app.apk", &diag);
    ASSERT_TRUE(result);
    EXPECT_EQ(result.value(), "app.ldpi_en-AU_df1_glx1.v26.mips64.apk");
  }
}

TEST(ArtifactTest, Missing) {
  StdErrDiagnostics diag;
  ConfiguredArtifact x86;
  x86.abi_group = {"x86"};

  EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "", &diag));
  EXPECT_FALSE(x86.ToArtifactName("something.apk", "", &diag));
  EXPECT_FALSE(x86.ToArtifactName("something.${density}.apk", "something.apk", &diag));
  EXPECT_FALSE(x86.ToArtifactName("something.apk", "something.apk", &diag));
}

TEST(ArtifactTest, Empty) {
  StdErrDiagnostics diag;
  ConfiguredArtifact artifact;

  EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
  EXPECT_TRUE(artifact.ToArtifactName("something.apk", "", &diag));
  EXPECT_FALSE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
  EXPECT_TRUE(artifact.ToArtifactName("something.apk", "something.apk", &diag));
}

TEST(ArtifactTest, Repeated) {
  StdErrDiagnostics diag;
  ConfiguredArtifact artifact;
  artifact.screen_density_group = {"mdpi"};

  ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "", &diag));
  EXPECT_FALSE(artifact.ToArtifactName("something.${density}.${density}.apk", "", &diag));
  ASSERT_TRUE(artifact.ToArtifactName("something.${density}.apk", "something.apk", &diag));
}

TEST(ArtifactTest, Nesting) {
  StdErrDiagnostics diag;
  ConfiguredArtifact x86;
  x86.abi_group = {"x86"};

  EXPECT_FALSE(x86.ToArtifactName("something.${abi${density}}.apk", "", &diag));

  const std::optional<std::string>& name =
      x86.ToArtifactName("something.${abi${abi}}.apk", "", &diag);
  ASSERT_TRUE(name);
  EXPECT_EQ(name.value(), "something.${abix86}.apk");
}

TEST(ArtifactTest, Recursive) {
  StdErrDiagnostics diag;
  ConfiguredArtifact artifact;
  artifact.device_feature_group = {"${gl}"};
  artifact.gl_texture_group = {"glx1"};

  EXPECT_FALSE(artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag));

  artifact.device_feature_group = {"df1"};
  artifact.gl_texture_group = {"${feature}"};
  {
    const auto& result = artifact.ToArtifactName("app.${feature}.${gl}.apk", "", &diag);
    ASSERT_TRUE(result);
    EXPECT_EQ(result.value(), "app.df1.${feature}.apk");
  }

  // This is an invalid case, but should be the only possible case due to the ordering of
  // replacement.
  artifact.device_feature_group = {"${gl}"};
  artifact.gl_texture_group = {"glx1"};
  {
    const auto& result = artifact.ToArtifactName("app.${feature}.apk", "", &diag);
    ASSERT_TRUE(result);
    EXPECT_EQ(result.value(), "app.glx1.apk");
  }
}

}  // namespace
}  // namespace handler
}  // namespace configuration
}  // namespace aapt
