/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "DominatorTree.h"

#include <sstream>
#include <string>
#include <vector>

#include "test/Test.h"
#include "util/Util.h"

namespace aapt {

namespace {

class PrettyPrinter : public DominatorTree::Visitor {
 public:
  explicit PrettyPrinter(const int indent = 2) : indent_(indent) {}

  void VisitTree(const std::string& product,
                 DominatorTree::Node* root) override {
    for (auto& child : root->children()) {
      VisitNode(child.get(), 0);
    }
  }

  std::string ToString(DominatorTree* tree) {
    buffer_.str("");
    buffer_.clear();
    tree->Accept(this);
    return buffer_.str();
  }

 private:
  void VisitConfig(const DominatorTree::Node* node, const int indent) {
    auto config_string = node->value()->config.toString();
    buffer_ << std::string(indent, ' ')
            << (config_string.isEmpty() ? "<default>" : config_string)
            << std::endl;
  }

  void VisitNode(const DominatorTree::Node* node, const int indent) {
    VisitConfig(node, indent);
    for (const auto& child : node->children()) {
      VisitNode(child.get(), indent + indent_);
    }
  }

  std::stringstream buffer_;
  const int indent_ = 2;
};

}  // namespace

TEST(DominatorTreeTest, DefaultDominatesEverything) {
  const ConfigDescription default_config = {};
  const ConfigDescription land_config = test::ParseConfigOrDie("land");
  const ConfigDescription sw600dp_land_config =
      test::ParseConfigOrDie("sw600dp-land-v13");

  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
  configs.push_back(
      util::make_unique<ResourceConfigValue>(sw600dp_land_config, ""));

  DominatorTree tree(configs);
  PrettyPrinter printer;

  std::string expected =
      "<default>\n"
      "  land\n"
      "  sw600dp-land-v13\n";
  EXPECT_EQ(expected, printer.ToString(&tree));
}

TEST(DominatorTreeTest, ProductsAreDominatedSeparately) {
  const ConfigDescription default_config = {};
  const ConfigDescription land_config = test::ParseConfigOrDie("land");
  const ConfigDescription sw600dp_land_config =
      test::ParseConfigOrDie("sw600dp-land-v13");

  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(land_config, ""));
  configs.push_back(
      util::make_unique<ResourceConfigValue>(default_config, "phablet"));
  configs.push_back(
      util::make_unique<ResourceConfigValue>(sw600dp_land_config, "phablet"));

  DominatorTree tree(configs);
  PrettyPrinter printer;

  std::string expected =
      "<default>\n"
      "  land\n"
      "<default>\n"
      "  sw600dp-land-v13\n";
  EXPECT_EQ(expected, printer.ToString(&tree));
}

TEST(DominatorTreeTest, MoreSpecificConfigurationsAreDominated) {
  const ConfigDescription default_config = {};
  const ConfigDescription en_config = test::ParseConfigOrDie("en");
  const ConfigDescription en_v21_config = test::ParseConfigOrDie("en-v21");
  const ConfigDescription ldrtl_config = test::ParseConfigOrDie("ldrtl-v4");
  const ConfigDescription ldrtl_xhdpi_config =
      test::ParseConfigOrDie("ldrtl-xhdpi-v4");
  const ConfigDescription sw300dp_config =
      test::ParseConfigOrDie("sw300dp-v13");
  const ConfigDescription sw540dp_config =
      test::ParseConfigOrDie("sw540dp-v14");
  const ConfigDescription sw600dp_config =
      test::ParseConfigOrDie("sw600dp-v14");
  const ConfigDescription sw720dp_config =
      test::ParseConfigOrDie("sw720dp-v13");
  const ConfigDescription v20_config = test::ParseConfigOrDie("v20");

  std::vector<std::unique_ptr<ResourceConfigValue>> configs;
  configs.push_back(util::make_unique<ResourceConfigValue>(default_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(en_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(en_v21_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(ldrtl_config, ""));
  configs.push_back(
      util::make_unique<ResourceConfigValue>(ldrtl_xhdpi_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(sw300dp_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(sw540dp_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(sw600dp_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(sw720dp_config, ""));
  configs.push_back(util::make_unique<ResourceConfigValue>(v20_config, ""));

  DominatorTree tree(configs);
  PrettyPrinter printer;

  std::string expected =
      "<default>\n"
      "  en\n"
      "    en-v21\n"
      "  ldrtl-v4\n"
      "    ldrtl-xhdpi-v4\n"
      "  sw300dp-v13\n"
      "    sw540dp-v14\n"
      "      sw600dp-v14\n"
      "    sw720dp-v13\n"
      "  v20\n";
  EXPECT_EQ(expected, printer.ToString(&tree));
}

}  // namespace aapt
