/*
 * 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_WINDOW_DRIVER_H_
#define COBALT_WEBDRIVER_WINDOW_DRIVER_H_

#if defined(ENABLE_WEBDRIVER)

#include <string>
#include <vector>

#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop_proxy.h"
#include "base/stl_util.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread_checker.h"
#include "cobalt/dom/keyboard_event.h"
#include "cobalt/dom/window.h"
#include "cobalt/webdriver/element_driver.h"
#include "cobalt/webdriver/element_mapping.h"
#include "cobalt/webdriver/protocol/cookie.h"
#include "cobalt/webdriver/protocol/frame_id.h"
#include "cobalt/webdriver/protocol/keys.h"
#include "cobalt/webdriver/protocol/script.h"
#include "cobalt/webdriver/protocol/search_strategy.h"
#include "cobalt/webdriver/protocol/size.h"
#include "cobalt/webdriver/protocol/window_id.h"
#include "cobalt/webdriver/script_executor.h"
#include "cobalt/webdriver/util/call_on_message_loop.h"
#include "cobalt/webdriver/util/command_result.h"

namespace cobalt {
namespace webdriver {

// A WebDriver windowHandle will map to a WindowDriver instance.
// WebDriver commands that interact with a Window, such as:
//     /session/:sessionId/window/:windowHandle/size
// will map to a method on this class.
class WindowDriver : private ElementMapping {
 public:
  typedef base::Callback<scoped_refptr<script::GlobalEnvironment>()>
      GetGlobalEnvironmentFunction;
  WindowDriver(const protocol::WindowId& window_id,
               const base::WeakPtr<dom::Window>& window,
               const GetGlobalEnvironmentFunction& get_global_environment,
               const scoped_refptr<base::MessageLoopProxy>& message_loop);
  ~WindowDriver();
  const protocol::WindowId& window_id() { return window_id_; }
  ElementDriver* GetElementDriver(const protocol::ElementId& element_id);

  util::CommandResult<protocol::Size> GetWindowSize();
  util::CommandResult<void> Navigate(const GURL& url);
  util::CommandResult<std::string> GetCurrentUrl();
  util::CommandResult<std::string> GetTitle();
  util::CommandResult<protocol::ElementId> FindElement(
      const protocol::SearchStrategy& strategy);
  util::CommandResult<std::vector<protocol::ElementId> > FindElements(
      const protocol::SearchStrategy& strategy);
  // Note: The source may be a fairly large string that is being copied around
  // by value here.
  util::CommandResult<std::string> GetSource();
  util::CommandResult<protocol::ScriptResult> Execute(
      const protocol::Script& script);
  util::CommandResult<void> SendKeys(const protocol::Keys& keys);
  util::CommandResult<protocol::ElementId> GetActiveElement();
  util::CommandResult<void> SwitchFrame(const protocol::FrameId& frame_id);
  util::CommandResult<std::vector<protocol::Cookie> > GetAllCookies();
  util::CommandResult<std::vector<protocol::Cookie> > GetCookie(
      const std::string& name);
  util::CommandResult<void> AddCookie(const protocol::Cookie& cookie);

 private:
  typedef base::hash_map<std::string, ElementDriver*> ElementDriverMap;
  typedef ElementDriverMap::iterator ElementDriverMapIt;
  typedef std::vector<protocol::ElementId> ElementIdVector;
  typedef std::vector<scoped_refptr<dom::KeyboardEvent> > KeyboardEventVector;

  // ScriptExecutor::ElementMapping implementation.
  protocol::ElementId ElementToId(
      const scoped_refptr<dom::Element>& element) OVERRIDE;
  scoped_refptr<dom::Element> IdToElement(
      const protocol::ElementId& id) OVERRIDE;

  dom::Window* GetWeak() {
    DCHECK_EQ(base::MessageLoopProxy::current(), window_message_loop_);
    return window_.get();
  }

  // Create a new ElementDriver that wraps this weak_element and return the
  // ElementId that maps to the new ElementDriver.
  protocol::ElementId CreateNewElementDriver(
      const base::WeakPtr<dom::Element>& weak_element);

  // Shared logic between FindElement and FindElements.
  template <typename T>
  util::CommandResult<T> FindElementsInternal(
      const protocol::SearchStrategy& strategy);

  util::CommandResult<protocol::ScriptResult> ExecuteScriptInternal(
      const protocol::Script& script);

  util::CommandResult<void> SendKeysInternal(
      scoped_ptr<KeyboardEventVector> keyboard_events);

  util::CommandResult<void> NavigateInternal(const GURL& url);

  util::CommandResult<void> AddCookieInternal(const protocol::Cookie& cookie);

  util::CommandResult<protocol::ElementId> GetActiveElementInternal();

  const protocol::WindowId window_id_;

  // Bound to the WebDriver thread.
  base::ThreadChecker thread_checker_;

  // Anything that interacts with the window must be run on this message loop.
  scoped_refptr<base::MessageLoopProxy> window_message_loop_;

  // Weak handle to the dom::Window that must only be accessed from
  // |window_message_loop|
  base::WeakPtr<dom::Window> window_;

  // This must only be accessed from |window_message_loop_|.
  GetGlobalEnvironmentFunction get_global_environment_;

  // Helper object for commands that execute script. This must only be accessed
  // from the |window_message_loop_|.
  base::WeakPtr<ScriptExecutor> script_executor_;

  // Mapping of protocol::ElementId to ElementDriver*. This should only be
  // accessed from the |window_message_loop_|, though it will be destructed
  // from the WebDriver thread.
  ElementDriverMap element_drivers_;

  // Ensure ElementDrivers that this WindowDriver owns are deleted on
  // destruction of the WindowDriver.
  STLValueDeleter<ElementDriverMap> element_driver_map_deleter_;

  // Monotonically increasing number to provide unique element ids.
  int32 next_element_id_;
};

}  // namespace webdriver
}  // namespace cobalt

#endif  // defined(ENABLE_WEBDRIVER)
#endif  // COBALT_WEBDRIVER_WINDOW_DRIVER_H_
