// 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.

#include "cobalt/dom/window.h"

#include <algorithm>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/tokens.h"
#include "cobalt/cssom/css_computed_style_declaration.h"
#include "cobalt/cssom/user_agent_style_sheet.h"
#include "cobalt/dom/camera_3d.h"
#include "cobalt/dom/console.h"
#include "cobalt/dom/device_orientation_event.h"
#include "cobalt/dom/document.h"
#include "cobalt/dom/dom_settings.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/event.h"
#include "cobalt/dom/history.h"
#include "cobalt/dom/html_element.h"
#include "cobalt/dom/html_element_context.h"
#include "cobalt/dom/keyboard_event.h"
#include "cobalt/dom/location.h"
#include "cobalt/dom/media_source.h"
#include "cobalt/dom/mouse_event.h"
#include "cobalt/dom/mutation_observer_task_manager.h"
#include "cobalt/dom/navigator.h"
#include "cobalt/dom/performance.h"
#include "cobalt/dom/pointer_event.h"
#include "cobalt/dom/screen.h"
#include "cobalt/dom/storage.h"
#include "cobalt/dom/wheel_event.h"
#include "cobalt/dom/window_timers.h"
#include "cobalt/media_session/media_session_client.h"
#include "cobalt/script/javascript_engine.h"
#include "cobalt/speech/speech_synthesis.h"

using cobalt::media_session::MediaSession;

namespace cobalt {
namespace dom {

// This class fires the window's load event when the document is loaded.
class Window::RelayLoadEvent : public DocumentObserver {
 public:
  explicit RelayLoadEvent(Window* window) : window_(window) {}

  // From DocumentObserver.
  void OnLoad() OVERRIDE {
    window_->PostToDispatchEvent(FROM_HERE, base::Tokens::load());
  }
  void OnMutation() OVERRIDE {}
  void OnFocusChanged() OVERRIDE {}

 private:
  Window* window_;

  DISALLOW_COPY_AND_ASSIGN(RelayLoadEvent);
};

Window::Window(int width, int height, float device_pixel_ratio,
               base::ApplicationState initial_application_state,
               cssom::CSSParser* css_parser, Parser* dom_parser,
               loader::FetcherFactory* fetcher_factory,
               render_tree::ResourceProvider** resource_provider,
               loader::image::AnimatedImageTracker* animated_image_tracker,
               loader::image::ImageCache* image_cache,
               loader::image::ReducedCacheCapacityManager*
                   reduced_image_cache_capacity_manager,
               loader::font::RemoteTypefaceCache* remote_typeface_cache,
               loader::mesh::MeshCache* mesh_cache,
               LocalStorageDatabase* local_storage_database,
               media::CanPlayTypeHandler* can_play_type_handler,
               media::WebMediaPlayerFactory* web_media_player_factory,
               script::ExecutionState* execution_state,
               script::ScriptRunner* script_runner,
               script::ScriptValueFactory* script_value_factory,
               MediaSource::Registry* media_source_registry,
               DomStatTracker* dom_stat_tracker, const GURL& url,
               const std::string& user_agent, const std::string& language,
               const base::Callback<void(const GURL&)> navigation_callback,
               const base::Callback<void(const std::string&)>& error_callback,
               network_bridge::CookieJar* cookie_jar,
               const network_bridge::PostSender& post_sender,
               const std::string& default_security_policy,
               CspEnforcementType csp_enforcement_mode,
               const base::Closure& csp_policy_changed_callback,
               const base::Closure& ran_animation_frame_callbacks_callback,
               const base::Closure& window_close_callback,
               const base::Closure& window_minimize_callback,
               const scoped_refptr<input::Camera3D>& camera_3d,
               const scoped_refptr<MediaSession>& media_session,
               int csp_insecure_allowed_token, int dom_max_element_depth,
               float video_playback_rate_multiplier, ClockType clock_type,
               const base::Callback<bool(const std::string&)>&
                   splash_screen_cache_callback)
    : width_(width),
      height_(height),
      device_pixel_ratio_(device_pixel_ratio),
      is_resize_event_pending_(false),
#if defined(ENABLE_TEST_RUNNER)
      test_runner_(new TestRunner()),
#endif  // ENABLE_TEST_RUNNER
      html_element_context_(new HTMLElementContext(
          fetcher_factory, css_parser, dom_parser, can_play_type_handler,
          web_media_player_factory, script_runner, script_value_factory,
          media_source_registry, resource_provider, animated_image_tracker,
          image_cache, reduced_image_cache_capacity_manager,
          remote_typeface_cache, mesh_cache, dom_stat_tracker, language,
          initial_application_state, video_playback_rate_multiplier)),
      performance_(new Performance(
#if defined(ENABLE_TEST_RUNNER)
          clock_type == kClockTypeTestRunner ? test_runner_->GetClock() :
#endif
                                             new base::SystemMonotonicClock())),
      ALLOW_THIS_IN_INITIALIZER_LIST(document_(new Document(
          html_element_context_.get(),
          Document::Options(
              url, this,
              base::Bind(&Window::FireHashChangeEvent, base::Unretained(this)),
              performance_->timing()->GetNavigationStartClock(),
              navigation_callback, ParseUserAgentStyleSheet(css_parser),
              math::Size(width_, height_), cookie_jar, post_sender,
              default_security_policy, csp_enforcement_mode,
              csp_policy_changed_callback, csp_insecure_allowed_token,
              dom_max_element_depth)))),
      document_loader_(NULL),
      history_(new History()),
      navigator_(new Navigator(user_agent, language, media_session,
                               script_value_factory)),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          relay_on_load_event_(new RelayLoadEvent(this))),
      console_(new Console(execution_state)),
      ALLOW_THIS_IN_INITIALIZER_LIST(window_timers_(new WindowTimers(this))),
      ALLOW_THIS_IN_INITIALIZER_LIST(animation_frame_request_callback_list_(
          new AnimationFrameRequestCallbackList(this))),
      crypto_(new Crypto()),
      speech_synthesis_(new speech::SpeechSynthesis(navigator_)),
      ALLOW_THIS_IN_INITIALIZER_LIST(local_storage_(
          new Storage(this, Storage::kLocalStorage, local_storage_database))),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          session_storage_(new Storage(this, Storage::kSessionStorage, NULL))),
      screen_(new Screen(width, height)),
      ran_animation_frame_callbacks_callback_(
          ran_animation_frame_callbacks_callback),
      window_close_callback_(window_close_callback),
      window_minimize_callback_(window_minimize_callback),
      splash_screen_cache_callback_(splash_screen_cache_callback) {
#if !defined(ENABLE_TEST_RUNNER)
  UNREFERENCED_PARAMETER(clock_type);
#endif
  document_->AddObserver(relay_on_load_event_.get());
  html_element_context_->page_visibility_state()->AddObserver(this);
  SetCamera3D(camera_3d);

  // Document load start is deferred from this constructor so that we can be
  // guaranteed that this Window object is fully constructed before document
  // loading begins.
  MessageLoop::current()->PostTask(
      FROM_HERE, base::Bind(&Window::StartDocumentLoad, this, fetcher_factory,
                            url, dom_parser, error_callback));
}

void Window::StartDocumentLoad(
    loader::FetcherFactory* fetcher_factory, const GURL& url,
    Parser* dom_parser,
    const base::Callback<void(const std::string&)>& error_callback) {
  document_loader_.reset(
      new loader::Loader(base::Bind(&loader::FetcherFactory::CreateFetcher,
                                    base::Unretained(fetcher_factory), url),
                         dom_parser->ParseDocumentAsync(
                             document_, base::SourceLocation(url.spec(), 1, 1)),
                         error_callback));
}

const scoped_refptr<Document>& Window::document() const { return document_; }

const scoped_refptr<Location>& Window::location() const {
  return document_->location();
}

const scoped_refptr<History>& Window::history() const { return history_; }

// https://www.w3.org/TR/html5/browsers.html#dom-window-close
void Window::Close() {
  LOG(INFO) << __func__;
  if (!window_close_callback_.is_null()) {
    window_close_callback_.Run();
  }
}

void Window::Minimize() {
  if (!window_minimize_callback_.is_null()) {
    window_minimize_callback_.Run();
  }
}

const scoped_refptr<Navigator>& Window::navigator() const { return navigator_; }

scoped_refptr<cssom::CSSStyleDeclaration> Window::GetComputedStyle(
    const scoped_refptr<Element>& elt) {
  scoped_refptr<HTMLElement> html_element = elt->AsHTMLElement();
  if (html_element) {
    document_->UpdateComputedStyleOnElementAndAncestor(html_element);
    return html_element->css_computed_style_declaration();
  }
  return NULL;
}

scoped_refptr<cssom::CSSStyleDeclaration> Window::GetComputedStyle(
    const scoped_refptr<Element>& elt, const std::string& pseudoElt) {
  // The getComputedStyle(elt, pseudoElt) method must run these steps:
  // https://www.w3.org/TR/2013/WD-cssom-20131205/#dom-window-getcomputedstyle

  // 1. Let doc be the Document associated with the Window object on which the
  // method was invoked.
  DCHECK_EQ(document_, elt->node_document())
      << "getComputedStyle not supported for elements outside of the document";

  scoped_refptr<HTMLElement> html_element = elt->AsHTMLElement();
  scoped_refptr<cssom::CSSComputedStyleDeclaration> obj;
  if (html_element) {
    document_->UpdateComputedStyleOnElementAndAncestor(html_element);

    // 2. Let obj be elt.
    obj = html_element->css_computed_style_declaration();

    // 3. If pseudoElt is as an ASCII case-insensitive match for either
    // ':before' or '::before' let obj be the ::before pseudo-element of elt.
    if (LowerCaseEqualsASCII(pseudoElt, ":before") ||
        LowerCaseEqualsASCII(pseudoElt, "::before")) {
      PseudoElement* pseudo_element =
          html_element->pseudo_element(kBeforePseudoElementType);
      obj = pseudo_element ? pseudo_element->css_computed_style_declaration()
                           : NULL;
    }

    // 4. If pseudoElt is as an ASCII case-insensitive match for either ':after'
    // or '::after' let obj be the ::after pseudo-element of elt.
    if (LowerCaseEqualsASCII(pseudoElt, ":after") ||
        LowerCaseEqualsASCII(pseudoElt, "::after")) {
      PseudoElement* pseudo_element =
          html_element->pseudo_element(kAfterPseudoElementType);
      obj = pseudo_element ? pseudo_element->css_computed_style_declaration()
                           : NULL;
    }
  }
  // 5. Return a live CSS declaration block.
  return obj;
}

int32 Window::RequestAnimationFrame(
    const AnimationFrameRequestCallbackList::FrameRequestCallbackArg&
        callback) {
  return animation_frame_request_callback_list_->RequestAnimationFrame(
      callback);
}

void Window::CancelAnimationFrame(int32 handle) {
  animation_frame_request_callback_list_->CancelAnimationFrame(handle);
}

scoped_refptr<MediaQueryList> Window::MatchMedia(const std::string& query) {
  DCHECK(html_element_context_->css_parser());
  scoped_refptr<cssom::MediaList> media_list =
      html_element_context_->css_parser()->ParseMediaList(
          query, GetInlineSourceLocation());
  return make_scoped_refptr(new MediaQueryList(media_list, screen_));
}

const scoped_refptr<Screen>& Window::screen() { return screen_; }

scoped_refptr<Crypto> Window::crypto() const { return crypto_; }

int Window::SetTimeout(const WindowTimers::TimerCallbackArg& handler,
                       int timeout) {
  DLOG_IF(WARNING, timeout < 0)
      << "Window::SetTimeout received negative timeout: " << timeout;
  timeout = std::max(timeout, 0);

  int return_value = 0;
  if (window_timers_) {
    return_value = window_timers_->SetTimeout(handler, timeout);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }

  return return_value;
}

void Window::ClearTimeout(int handle) {
  if (window_timers_) {
    window_timers_->ClearTimeout(handle);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }
}

int Window::SetInterval(const WindowTimers::TimerCallbackArg& handler,
                        int timeout) {
  DLOG_IF(WARNING, timeout < 0)
      << "Window::SetInterval received negative timeout: " << timeout;
  timeout = std::max(timeout, 0);

  int return_value = 0;
  if (window_timers_) {
    return_value = window_timers_->SetInterval(handler, timeout);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }

  return return_value;
}

void Window::ClearInterval(int handle) {
  if (window_timers_) {
    window_timers_->ClearInterval(handle);
  } else {
    DLOG(WARNING) << "window_timers_ does not exist.  Already destroyed?";
  }
}

void Window::DestroyTimers() { window_timers_.reset(); }

scoped_refptr<Storage> Window::local_storage() const { return local_storage_; }

scoped_refptr<Storage> Window::session_storage() const {
  return session_storage_;
}

const scoped_refptr<Performance>& Window::performance() const {
  return performance_;
}

scoped_refptr<speech::SpeechSynthesis> Window::speech_synthesis() const {
  return speech_synthesis_;
}

const scoped_refptr<Console>& Window::console() const { return console_; }

const scoped_refptr<Camera3D>& Window::camera_3d() const { return camera_3d_; }

#if defined(ENABLE_TEST_RUNNER)
const scoped_refptr<TestRunner>& Window::test_runner() const {
  return test_runner_;
}
#endif  // ENABLE_TEST_RUNNER

void Window::Gc(script::EnvironmentSettings* settings) {
  if (settings) {
    DOMSettings* dom_settings =
        base::polymorphic_downcast<dom::DOMSettings*>(settings);
    dom_settings->javascript_engine()->CollectGarbage();
  }
}

HTMLElementContext* Window::html_element_context() const {
  return html_element_context_.get();
}

void Window::RunAnimationFrameCallbacks() {
  // Scope the StopWatch. It should not include any processing from
  // |ran_animation_frame_callbacks_callback_|.
  {
    base::StopWatch stop_watch_run_animation_frame_callbacks(
        DomStatTracker::kStopWatchTypeRunAnimationFrameCallbacks,
        base::StopWatch::kAutoStartOn,
        html_element_context()->dom_stat_tracker());

    // First grab the current list of frame request callbacks and hold on to it
    // here locally.
    scoped_ptr<AnimationFrameRequestCallbackList> frame_request_list =
        animation_frame_request_callback_list_.Pass();

    // Then setup the Window's frame request callback list with a freshly
    // created and empty one.
    animation_frame_request_callback_list_.reset(
        new AnimationFrameRequestCallbackList(this));

    // Now, iterate through each of the callbacks and call them.
    frame_request_list->RunCallbacks(*document_->timeline()->current_time());
  }

  // Run the callback if one exists.
  if (!ran_animation_frame_callbacks_callback_.is_null()) {
    ran_animation_frame_callbacks_callback_.Run();
  }
}

bool Window::HasPendingAnimationFrameCallbacks() const {
  return animation_frame_request_callback_list_->HasPendingCallbacks();
}

void Window::InjectEvent(const scoped_refptr<Event>& event) {
  // Forward the event on to the correct object in DOM.
  if (event->GetWrappableType() == base::GetTypeId<KeyboardEvent>()) {
    // Event.target:focused element processing the key event or if no element
    // focused, then the body element if available, otherwise the root element.
    //   https://www.w3.org/TR/2016/WD-uievents-20160804/#event-type-keydown
    //   https://www.w3.org/TR/2016/WD-uievents-20160804/#event-type-keypress
    //   https://www.w3.org/TR/2016/WD-uievents-20160804/#event-type-keyup
    if (document_->active_element()) {
      document_->active_element()->DispatchEvent(event);
    } else {
      document_->DispatchEvent(event);
    }
  } else if (event->GetWrappableType() == base::GetTypeId<PointerEvent>() ||
             event->GetWrappableType() == base::GetTypeId<MouseEvent>() ||
             event->GetWrappableType() == base::GetTypeId<WheelEvent>()) {
    document_->pointer_state()->QueuePointerEvent(event);
  } else {
    SB_NOTREACHED();
  }
}

void Window::SetApplicationState(base::ApplicationState state) {
  html_element_context_->page_visibility_state()->SetApplicationState(state);
}

void Window::SetSynchronousLayoutCallback(
    const base::Closure& synchronous_layout_callback) {
  document_->set_synchronous_layout_callback(synchronous_layout_callback);
}

void Window::SetSize(int width, int height, float device_pixel_ratio) {
  if (width_ == width && height_ == height &&
      device_pixel_ratio_ == device_pixel_ratio) {
    return;
  }

  width_ = width;
  height_ = height;
  device_pixel_ratio_ = device_pixel_ratio;
  screen_->SetSize(width, height);

  // This will cause layout invalidation.
  document_->SetViewport(math::Size(width, height));

  if (html_element_context_->page_visibility_state()->GetVisibilityState() ==
      page_visibility::kVisibilityStateVisible) {
    DispatchEvent(new Event(base::Tokens::resize()));
  } else {
    is_resize_event_pending_ = true;
  }
}

void Window::SetCamera3D(const scoped_refptr<input::Camera3D>& camera_3d) {
  camera_3d_ = new Camera3D(camera_3d);
  camera_3d_->StartOrientationEvents(base::AsWeakPtr(this));
}

void Window::OnWindowFocusChanged(bool has_focus) {
  DispatchEvent(
      new Event(has_focus ? base::Tokens::focus() : base::Tokens::blur()));
}

void Window::OnVisibilityStateChanged(
    page_visibility::VisibilityState visibility_state) {
  if (is_resize_event_pending_ &&
      visibility_state == page_visibility::kVisibilityStateVisible) {
    is_resize_event_pending_ = false;
    DispatchEvent(new Event(base::Tokens::resize()));
  }
}

void Window::TraceMembers(script::Tracer* tracer) {
  tracer->Trace(performance_);
  tracer->Trace(document_);
  tracer->Trace(history_);
  tracer->Trace(navigator_);
  tracer->Trace(console_);
  tracer->Trace(camera_3d_);
  tracer->Trace(crypto_);
  tracer->Trace(speech_synthesis_);
  tracer->Trace(local_storage_);
  tracer->Trace(session_storage_);
  tracer->Trace(screen_);
}

Window::~Window() {
  html_element_context_->page_visibility_state()->RemoveObserver(this);
}

void Window::FireHashChangeEvent() {
  PostToDispatchEvent(FROM_HERE, base::Tokens::hashchange());
}

}  // namespace dom
}  // namespace cobalt
