// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// 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 "cobalt/cssom/compound_selector.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "cobalt/cssom/pseudo_element.h"
#include "cobalt/cssom/selector_visitor.h"

namespace cobalt {
namespace cssom {
namespace {

bool SimpleSelectorsLessThan(const std::unique_ptr<SimpleSelector>& lhs,
                             const std::unique_ptr<SimpleSelector>& rhs) {
  if (lhs->type() < rhs->type()) {
    return true;
  }
  if (rhs->type() < lhs->type()) {
    return false;
  }
  if (lhs->text() < rhs->text()) {
    return true;
  }
  if (rhs->text() < lhs->text()) {
    return false;
  }
  if (lhs->value() < rhs->value()) {
    return true;
  }
  if (rhs->value() < lhs->value()) {
    return false;
  }

  // Pseudo class selectors may contain compound selectors, which also need to
  // be compared.
  if (lhs->type() == kPseudoClass) {
    CompoundSelector* lhs_compound_selector =
        lhs->GetContainedCompoundSelector();
    CompoundSelector* rhs_compound_selector =
        rhs->GetContainedCompoundSelector();
    if (lhs_compound_selector && rhs_compound_selector) {
      if (*lhs_compound_selector < *rhs_compound_selector) {
        return true;
      }
      if (*rhs_compound_selector < *lhs_compound_selector) {
        return false;
      }
    } else if (rhs_compound_selector) {
      return true;
    } else if (lhs_compound_selector) {
      return false;
    }
  }

  return false;
}

}  // namespace

CompoundSelector::CompoundSelector()
    : left_combinator_(NULL),
      has_pseudo_element_(false),
      requires_rule_matching_verification_visit_(false) {}

CompoundSelector::~CompoundSelector() {}

bool CompoundSelector::operator<(const CompoundSelector& that) const {
  if (simple_selectors_.size() < that.simple_selectors_.size()) {
    return true;
  }
  if (that.simple_selectors_.size() < simple_selectors_.size()) {
    return false;
  }

  for (size_t i = 0; i < simple_selectors_.size(); ++i) {
    if (SimpleSelectorsLessThan(simple_selectors_[i],
                                that.simple_selectors_[i])) {
      return true;
    }
    if (SimpleSelectorsLessThan(that.simple_selectors_[i],
                                simple_selectors_[i])) {
      return false;
    }
  }

  return false;
}

void CompoundSelector::Accept(SelectorVisitor* visitor) {
  visitor->VisitCompoundSelector(this);
}

void CompoundSelector::AppendSelector(
    std::unique_ptr<SimpleSelector> simple_selector) {
  specificity_.AddFrom(simple_selector->GetSpecificity());
  has_pseudo_element_ =
      has_pseudo_element_ || simple_selector->AsPseudoElement() != NULL;

  // There are two cases where the selectors require a visit:
  // 1. There are multiple selectors. Gathering only tests against the first
  //    selector and the later selectors must also be verified to match.
  // 2. The single selector's AlwaysRequiresRuleMatchingVerificationVisit() call
  //    returns true. This indicates that being gathered as a candidate is not
  //    sufficient to prove a match and that additional verification checks are
  //    required.
  requires_rule_matching_verification_visit_ =
      requires_rule_matching_verification_visit_ ||
      !simple_selectors_.empty() ||
      simple_selector->AlwaysRequiresRuleMatchingVerificationVisit();

  // Insert the new selector in sorted order.
  auto pos =
      std::lower_bound(simple_selectors_.begin(), simple_selectors_.end(),
                       simple_selector, SimpleSelectorsLessThan);
  simple_selectors_.insert(pos, std::move(simple_selector));
}

void CompoundSelector::set_right_combinator(
    std::unique_ptr<Combinator> combinator) {
  right_combinator_ = std::move(combinator);
}

}  // namespace cssom
}  // namespace cobalt
