/*
 * Copyright (C) 2008, 2009, 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/bindings/core/v8/window_proxy.h"

#include <utility>

#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.h"
#include "third_party/blink/renderer/core/frame/dom_window.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"
#include "v8/include/v8.h"

namespace blink {

WindowProxy::~WindowProxy() {
  // clearForClose() or clearForNavigation() must be invoked before destruction
  // starts.
  DCHECK(lifecycle_ != Lifecycle::kContextIsInitialized);
}

void WindowProxy::Trace(Visitor* visitor) const {
  visitor->Trace(frame_);
  visitor->Trace(global_proxy_);
}

WindowProxy::WindowProxy(v8::Isolate* isolate,
                         Frame& frame,
                         scoped_refptr<DOMWrapperWorld> world)
    : isolate_(isolate),
      frame_(frame),

      world_(std::move(world)),
      lifecycle_(Lifecycle::kContextIsUninitialized) {}

void WindowProxy::ClearForClose() {
  DisposeContext(lifecycle_ == Lifecycle::kV8MemoryIsForciblyPurged
                     ? Lifecycle::kFrameIsDetachedAndV8MemoryIsPurged
                     : Lifecycle::kFrameIsDetached,
                 kFrameWillNotBeReused);
}

void WindowProxy::ClearForNavigation() {
  DisposeContext(Lifecycle::kGlobalObjectIsDetached, kFrameWillBeReused);
}

void WindowProxy::ClearForSwap() {
  DisposeContext(Lifecycle::kGlobalObjectIsDetached, kFrameWillNotBeReused);
}

void WindowProxy::ClearForV8MemoryPurge() {
  DisposeContext(Lifecycle::kV8MemoryIsForciblyPurged, kFrameWillNotBeReused);
}

v8::Local<v8::Object> WindowProxy::GlobalProxyIfNotDetached() {
  if (lifecycle_ == Lifecycle::kContextIsInitialized) {
    DLOG_IF(FATAL, !is_global_object_attached_)
        << "Context is initialized but global object is detached!";
    return global_proxy_.NewLocal(isolate_);
  }
  return v8::Local<v8::Object>();
}

v8::Local<v8::Object> WindowProxy::ReleaseGlobalProxy() {
  DCHECK(lifecycle_ == Lifecycle::kContextIsUninitialized ||
         lifecycle_ == Lifecycle::kGlobalObjectIsDetached);

  // Make sure the global object was detached from the proxy by calling
  // ClearForSwap().
  DLOG_IF(FATAL, is_global_object_attached_)
      << "Context not detached by calling ClearForSwap()";

  v8::Local<v8::Object> global_proxy = global_proxy_.NewLocal(isolate_);
  global_proxy_.Clear();
  return global_proxy;
}

void WindowProxy::SetGlobalProxy(v8::Local<v8::Object> global_proxy) {
  DCHECK_EQ(lifecycle_, Lifecycle::kContextIsUninitialized);

  CHECK(global_proxy_.IsEmpty());
  global_proxy_.Set(isolate_, global_proxy);
  // The global proxy was transferred from a previous WindowProxy, so the state
  // should be detached, not uninitialized. This ensures that it will be
  // properly reinitialized when needed, e.g. by `UpdateDocument()`.
  lifecycle_ = Lifecycle::kGlobalObjectIsDetached;
}

// Create a new environment and setup the global object.
//
// The global object corresponds to a DOMWindow instance. However, to
// allow properties of the JS DOMWindow instance to be shadowed, we
// use a shadow object as the global object and use the JS DOMWindow
// instance as the prototype for that shadow object. The JS DOMWindow
// instance is undetectable from JavaScript code because the __proto__
// accessors skip that object.
//
// The shadow object and the DOMWindow instance are seen as one object
// from JavaScript. The JavaScript object that corresponds to a
// DOMWindow instance is the shadow object. When mapping a DOMWindow
// instance to a V8 object, we return the shadow object.
//
// To implement split-window, see
//   1) https://bugs.webkit.org/show_bug.cgi?id=17249
//   2) https://wiki.mozilla.org/Gecko:SplitWindow
//   3) https://bugzilla.mozilla.org/show_bug.cgi?id=296639
// we need to split the shadow object further into two objects:
// an outer window and an inner window. The inner window is the hidden
// prototype of the outer window. The inner window is the default
// global object of the context. A variable declared in the global
// scope is a property of the inner window.
//
// The outer window sticks to a LocalFrame, it is exposed to JavaScript
// via window.window, window.self, window.parent, etc. The outer window
// has a security token which is the domain. The outer window cannot
// have its own properties. window.foo = 'x' is delegated to the
// inner window.
//
// When a frame navigates to a new page, the inner window is cut off
// the outer window, and the outer window identify is preserved for
// the frame. However, a new inner window is created for the new page.
// If there are JS code holds a closure to the old inner window,
// it won't be able to reach the outer window via its global object.
void WindowProxy::InitializeIfNeeded() {
  if (lifecycle_ == Lifecycle::kContextIsUninitialized ||
      lifecycle_ == Lifecycle::kGlobalObjectIsDetached) {
    Initialize();
  }
}

}  // namespace blink
