/*
 *  Copyright (C) 2000 Harri Porten (porten@kde.org)
 *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reseved.
 *  Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 *  USA
 */

#include "config.h"
#include "JSLocation.h"

#include "DOMWindow.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "PlatformString.h"
#include "kjs_proxy.h"
#include "kjs_window.h"

#include "JSLocation.lut.h"

using namespace KJS;

namespace WebCore {

const ClassInfo JSLocation::info = { "Location", 0, &JSLocationTable };

/*
@begin JSLocationTable 12
  assign        WebCore::jsLocationProtoFuncAssign        DontDelete|Function 1
  hash          WebCore::JSLocation::Hash                 DontDelete
  host          WebCore::JSLocation::Host                 DontDelete
  hostname      WebCore::JSLocation::Hostname             DontDelete
  href          WebCore::JSLocation::Href                 DontDelete
  pathname      WebCore::JSLocation::Pathname             DontDelete
  port          WebCore::JSLocation::Port                 DontDelete
  protocol      WebCore::JSLocation::Protocol             DontDelete
  search        WebCore::JSLocation::Search               DontDelete
  toString      WebCore::jsLocationProtoFuncToString      DontEnum|DontDelete|Function 0
  replace       WebCore::jsLocationProtoFuncReplace       DontDelete|Function 1
  reload        WebCore::jsLocationProtoFuncReload        DontDelete|Function 0
@end
*/

JSLocation::JSLocation(JSObject* /*prototype*/, Frame* frame)
    : DOMObject(jsNull()) // FIXME: this needs to take a real prototype
    , m_frame(frame)
{
}

JSValue* JSLocation::getValueProperty(ExecState* exec, int token) const
{
  const KURL& url = m_frame->loader()->url();
  switch (token) {
  case Hash:
    return jsString(url.ref().isNull() ? "" : "#" + url.ref());
  case Host: {
    // Note: this is the IE spec. The NS spec swaps the two, it says
    // "The hostname property is the concatenation of the host and port properties, separated by a colon."
    // Bleh.
    UString str = url.host();
    if (url.port())
        str += ":" + String::number((int)url.port());
    return jsString(str);
  }
  case Hostname:
    return jsString(url.host());
  case Href:
    if (!url.hasPath())
      return jsString(url.prettyURL() + "/");
    return jsString(url.prettyURL());
  case Pathname:
    return jsString(url.path().isEmpty() ? "/" : url.path());
  case Port:
    return jsString(url.port() ? String::number((int)url.port()) : "");
  case Protocol:
    return jsString(url.protocol() + ":");
  case Search:
    return jsString(url.query());
  default:
    ASSERT_NOT_REACHED();
    return jsUndefined();
  }
}

bool JSLocation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    if (customGetOwnPropertySlot(exec, propertyName, slot))
        return true;
    return getStaticPropertySlot<JSLocation, JSObject>(exec, &JSLocationTable, this, propertyName, slot);
}

bool JSLocation::customGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    // When accessing Location cross-domain, functions are always the native built-in ones.
    // See JSDOMWindow::customGetOwnPropertySlot for additional details.

    // Our custom code is only needed to implement the Window cross-domain scheme, so if access is
    // allowed, return false so the normal lookup will take place.
    String message;
    if (allowsAccessFromFrame(exec, m_frame, message))
        return false;

    // Check for the few functions that we allow, even when called cross-domain.
    const HashEntry* entry = Lookup::findEntry(&JSLocationTable, propertyName);
    if (entry && (entry->attr & Function)
            && (entry->value.functionValue == jsLocationProtoFuncReplace
                || entry->value.functionValue == jsLocationProtoFuncReload
                || entry->value.functionValue == jsLocationProtoFuncAssign)) {
        slot.setStaticEntry(this, entry, nonCachingStaticFunctionGetter);
        return true;
    }
    // FIXME: Other implementers of the Window cross-domain scheme (Window, History) allow toString,
    // but for now we have decided not to, partly because it seems silly to return "[Object Location]" in
    // such cases when normally the string form of Location would be the URL.

    printErrorMessageForFrame(m_frame, message);
    slot.setUndefined(this);
    return true;
}

void JSLocation::put(ExecState* exec, const Identifier& propertyName, JSValue* value, int attr)
{
  if (!m_frame)
    return;

  DeprecatedString str = value->toString(exec);
  KURL url = m_frame->loader()->url();
  bool sameDomainAccess = allowsAccessFromFrame(exec, m_frame);

  const HashEntry* entry = Lookup::findEntry(&JSLocationTable, propertyName);

  if (entry) {
      // cross-domain access to the location is allowed when assigning the whole location,
      // but not when assigning the individual pieces, since that might inadvertently
      // disclose other parts of the original location.
      if (entry->value.intValue != Href && !sameDomainAccess)
          return;

      switch (entry->value.intValue) {
      case Href: {
          Frame* frame = Window::retrieveActive(exec)->impl()->frame();
          if (!frame)
              return;
          if (!frame->loader()->shouldAllowNavigation(m_frame))
              return;
          url = frame->loader()->completeURL(str);
          break;
      }
      case Hash: {
          if (str.startsWith("#"))
              str = str.mid(1);
          if (url.ref() == str)
              return;
          url.setRef(str);
          break;
      }
      case Host: {
          url.setHostAndPort(str);
          break;
      }
      case Hostname:
          url.setHost(str);
          break;
      case Pathname:
          url.setPath(str);
          break;
      case Port:
          url.setPort(str.toUInt());
          break;
      case Protocol:
          url.setProtocol(str);
          break;
      case Search:
          url.setQuery(str);
          break;
      default:
          // Disallow changing other properties in JSLocationTable. e.g., "window.location.toString = ...".
          // <http://bugs.webkit.org/show_bug.cgi?id=12720>
          return;
      }
  } else {
      if (sameDomainAccess)
          JSObject::put(exec, propertyName, value, attr);
      return;
  }

  Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
  if (!url.deprecatedString().startsWith("javascript:", false) || sameDomainAccess) {
    bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
    m_frame->loader()->scheduleLocationChange(url.string(), activeFrame->loader()->outgoingReferrer(), false, userGesture);
  }
}

bool JSLocation::deleteProperty(ExecState* exec, const Identifier& propertyName)
{
    // Only allow deleting by frames in the same origin.
    if (!allowsAccessFromFrame(exec, m_frame))
        return false;
    return Base::deleteProperty(exec, propertyName);
}

void JSLocation::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
    // Only allow the location object to enumerated by frames in the same origin.
    if (!allowsAccessFromFrame(exec, m_frame))
        return;
    Base::getPropertyNames(exec, propertyNames);
}

JSValue* jsLocationProtoFuncReplace(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&JSLocation::info))
        return throwError(exec, TypeError);
    JSLocation* location = static_cast<JSLocation*>(thisObj);
    Frame* frame = location->frame();
    if (!frame)
        return jsUndefined();

    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    if (activeFrame) {
        if (!activeFrame->loader()->shouldAllowNavigation(frame))
            return jsUndefined();
        DeprecatedString str = args[0]->toString(exec);
        const Window* window = Window::retrieveWindow(frame);
        if (!str.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
            bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
            frame->loader()->scheduleLocationChange(activeFrame->loader()->completeURL(str).string(), activeFrame->loader()->outgoingReferrer(), true, userGesture);
        }
    }

    return jsUndefined();
}

JSValue* jsLocationProtoFuncReload(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&JSLocation::info))
        return throwError(exec, TypeError);
    JSLocation* location = static_cast<JSLocation*>(thisObj);
    Frame* frame = location->frame();
    if (!frame)
        return jsUndefined();

    Window* window = Window::retrieveWindow(frame);
    if (!window->allowsAccessFrom(exec))
        return jsUndefined();

    if (!frame->loader()->url().deprecatedString().startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
        bool userGesture = Window::retrieveActive(exec)->impl()->frame()->scriptProxy()->processingUserGesture();
        frame->loader()->scheduleRefresh(userGesture);
    }
    return jsUndefined();
}

JSValue* jsLocationProtoFuncAssign(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&JSLocation::info))
        return throwError(exec, TypeError);
    JSLocation* location = static_cast<JSLocation*>(thisObj);
    Frame* frame = location->frame();
    if (!frame)
        return jsUndefined();

    Frame* activeFrame = Window::retrieveActive(exec)->impl()->frame();
    if (activeFrame) {
        if (!activeFrame->loader()->shouldAllowNavigation(frame))
            return jsUndefined();
        const Window* window = Window::retrieveWindow(frame);
        String dstUrl = activeFrame->loader()->completeURL(args[0]->toString(exec)).string();
        if (!dstUrl.startsWith("javascript:", false) || (window && window->allowsAccessFrom(exec))) {
            bool userGesture = activeFrame->scriptProxy()->processingUserGesture();
            // We want a new history item if this JS was called via a user gesture
            frame->loader()->scheduleLocationChange(dstUrl, activeFrame->loader()->outgoingReferrer(), false, userGesture);
        }
    }

    return jsUndefined();
}

JSValue* jsLocationProtoFuncToString(ExecState* exec, JSObject* thisObj, const List& args)
{
    if (!thisObj->inherits(&JSLocation::info))
        return throwError(exec, TypeError);
    JSLocation* location = static_cast<JSLocation*>(thisObj);
    Frame* frame = location->frame();
    if (!frame)
        return jsUndefined();
    if (!allowsAccessFromFrame(exec, frame))
        return jsUndefined();

    const KURL& url = frame->loader()->url();
    if (!url.hasPath())
        return jsString(url.prettyURL() + "/");
    return jsString(url.prettyURL());
}

} // namespace WebCore
