/*
 * 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 <algorithm>

#include "android-base/logging.h"
#include "androidfw/ConfigDescription.h"

using ::android::ConfigDescription;

namespace aapt {

DominatorTree::DominatorTree(
    const std::vector<std::unique_ptr<ResourceConfigValue>>& configs) {
  for (const auto& config : configs) {
    product_roots_[config->product].TryAddChild(
        util::make_unique<Node>(config.get(), nullptr));
  }
}

void DominatorTree::Accept(Visitor* visitor) {
  for (auto& entry : product_roots_) {
    visitor->VisitTree(entry.first, &entry.second);
  }
}

bool DominatorTree::Node::TryAddChild(std::unique_ptr<Node> new_child) {
  CHECK(new_child->value_) << "cannot add a root or empty node as a child";
  if (value_ && !Dominates(new_child.get())) {
    // This is not the root and the child dominates us.
    return false;
  }
  return AddChild(std::move(new_child));
}

bool DominatorTree::Node::AddChild(std::unique_ptr<Node> new_child) {
  bool has_dominated_children = false;
  // Demote children dominated by the new config.
  for (auto& child : children_) {
    if (new_child->Dominates(child.get())) {
      child->parent_ = new_child.get();
      new_child->children_.push_back(std::move(child));
      child = {};
      has_dominated_children = true;
    }
  }
  // Remove dominated children.
  if (has_dominated_children) {
    children_.erase(
        std::remove_if(children_.begin(), children_.end(),
                       [](const std::unique_ptr<Node>& child) -> bool {
                         return child == nullptr;
                       }),
        children_.end());
  }
  // Add the new config to a child if a child dominates the new config.
  for (auto& child : children_) {
    if (child->Dominates(new_child.get())) {
      child->AddChild(std::move(new_child));
      return true;
    }
  }
  // The new config is not dominated by a child, so add it here.
  new_child->parent_ = this;
  children_.push_back(std::move(new_child));
  return true;
}

bool DominatorTree::Node::Dominates(const Node* other) const {
  // Check root node dominations.
  if (other->is_root_node()) {
    return is_root_node();
  } else if (is_root_node()) {
    return true;
  }
  // Neither node is a root node; compare the configurations.
  return value_->config.Dominates(other->value_->config);
}

}  // namespace aapt
