// Copyright 2015 Google Inc. 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.

#ifndef COBALT_WEBDRIVER_SEARCH_H_
#define COBALT_WEBDRIVER_SEARCH_H_

#include <vector>

#include "base/memory/ref_counted.h"
#include "cobalt/dom/html_collection.h"
#include "cobalt/dom/node_list.h"
#include "cobalt/webdriver/element_mapping.h"
#include "cobalt/webdriver/protocol/search_strategy.h"
#include "cobalt/webdriver/util/command_result.h"

namespace cobalt {
namespace webdriver {

class Search {
 public:
  template <typename T, typename N>
  static util::CommandResult<T> FindElementsUnderNode(
      const protocol::SearchStrategy& strategy, N* node,
      ElementMapping* element_mapping) {
    typedef util::CommandResult<T> CommandResult;
    ElementVector found_elements;
    switch (strategy.strategy()) {
      case protocol::SearchStrategy::kClassName: {
        scoped_refptr<dom::HTMLCollection> collection =
            node->GetElementsByClassName(strategy.parameter());
        HTMLCollectionToElementVector(collection, &found_elements);
        break;
      }
      case protocol::SearchStrategy::kTagName: {
        scoped_refptr<dom::HTMLCollection> collection =
            node->GetElementsByTagName(strategy.parameter());
        HTMLCollectionToElementVector(collection, &found_elements);
        break;
      }
      case protocol::SearchStrategy::kCssSelector: {
        scoped_refptr<dom::NodeList> node_list =
            node->QuerySelectorAll(strategy.parameter());
        NodeListToElementVector(node_list, &found_elements);
        break;
      }
      default:
        NOTIMPLEMENTED();
    }
    return PopulateFindResults<T>(found_elements, element_mapping);
  }

 private:
  typedef std::vector<scoped_refptr<dom::Element> > ElementVector;
  typedef std::vector<protocol::ElementId> ElementIdVector;

  template <typename T>
  static util::CommandResult<T> PopulateFindResults(
      const ElementVector& found_elements, ElementMapping* element_mapping);

  static void HTMLCollectionToElementVector(
      const scoped_refptr<dom::HTMLCollection>& html_collection,
      ElementVector* element_vector);
  static void NodeListToElementVector(
      const scoped_refptr<dom::NodeList>& node_list,
      ElementVector* element_vector);
};

}  // namespace webdriver
}  // namespace cobalt
#endif  // COBALT_WEBDRIVER_SEARCH_H_
