/*
 *  Copyright (C) 2000 Harri Porten (porten@kde.org)
 *  Copyright (C) 2006 Jon Shier (jshier@iastate.edu)
 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010 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 "core/page/WindowFeatures.h"

#include "platform/geometry/IntRect.h"
#include "wtf/Assertions.h"
#include "wtf/MathExtras.h"
#include "wtf/text/StringHash.h"

namespace blink {

// Though isspace() considers \t and \v to be whitespace, Win IE doesn't when
// parsing window features.
static bool isWindowFeaturesSeparator(UChar c) {
  return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '=' ||
         c == ',' || c == '\0';
}

WindowFeatures::WindowFeatures(const String& features)
    : x(0),
      xSet(false),
      y(0),
      ySet(false),
      width(0),
      widthSet(false),
      height(0),
      heightSet(false),
      resizable(true),
      fullscreen(false),
      dialog(false),
      noopener(false) {
  /*
     The IE rule is: all features except for channelmode and fullscreen default
     to YES, but if the user specifies a feature string, all features default to
     NO. (There is no public standard that applies to this method.)

     <http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/open_0.asp>
     We always allow a window to be resized, which is consistent with Firefox.
     */

  if (features.isEmpty()) {
    menuBarVisible = true;
    statusBarVisible = true;
    toolBarVisible = true;
    locationBarVisible = true;
    scrollbarsVisible = true;
    return;
  }

  menuBarVisible = false;
  statusBarVisible = false;
  toolBarVisible = false;
  locationBarVisible = false;
  scrollbarsVisible = false;

  // Tread lightly in this code -- it was specifically designed to mimic Win
  // IE's parsing behavior.
  unsigned keyBegin, keyEnd;
  unsigned valueBegin, valueEnd;

  String buffer = features.lower();
  unsigned length = buffer.length();
  for (unsigned i = 0; i < length;) {
    // skip to first non-separator, but don't skip past the end of the string
    while (i < length && isWindowFeaturesSeparator(buffer[i]))
      i++;
    keyBegin = i;

    // skip to first separator
    while (i < length && !isWindowFeaturesSeparator(buffer[i]))
      i++;
    keyEnd = i;

    ASSERT_WITH_SECURITY_IMPLICATION(i <= length);

    // skip to first '=', but don't skip past a ',' or the end of the string
    while (i < length && buffer[i] != '=') {
      if (buffer[i] == ',')
        break;
      i++;
    }

    ASSERT_WITH_SECURITY_IMPLICATION(i <= length);

    // Skip to first non-separator, but don't skip past a ',' or the end of the
    // string.
    while (i < length && isWindowFeaturesSeparator(buffer[i])) {
      if (buffer[i] == ',')
        break;
      i++;
    }
    valueBegin = i;

    ASSERT_WITH_SECURITY_IMPLICATION(i <= length);

    // skip to first separator
    while (i < length && !isWindowFeaturesSeparator(buffer[i]))
      i++;
    valueEnd = i;

    ASSERT_WITH_SECURITY_IMPLICATION(i <= length);

    String keyString(buffer.substring(keyBegin, keyEnd - keyBegin));
    String valueString(buffer.substring(valueBegin, valueEnd - valueBegin));

    setWindowFeature(keyString, valueString);
  }
}

void WindowFeatures::setWindowFeature(const String& keyString,
                                      const String& valueString) {
  int value;

  // Listing a key with no value is shorthand for key=yes
  if (valueString.isEmpty() || valueString == "yes")
    value = 1;
  else
    value = valueString.toInt();

  // We treat keyString of "resizable" here as an additional feature rather than
  // setting resizeable to true.  This is consistent with Firefox, but could
  // also be handled at another level.

  if (keyString == "left" || keyString == "screenx") {
    xSet = true;
    x = value;
  } else if (keyString == "top" || keyString == "screeny") {
    ySet = true;
    y = value;
  } else if (keyString == "width" || keyString == "innerwidth") {
    widthSet = true;
    width = value;
  } else if (keyString == "height" || keyString == "innerheight") {
    heightSet = true;
    height = value;
  } else if (keyString == "menubar") {
    menuBarVisible = value;
  } else if (keyString == "toolbar") {
    toolBarVisible = value;
  } else if (keyString == "location") {
    locationBarVisible = value;
  } else if (keyString == "status") {
    statusBarVisible = value;
  } else if (keyString == "fullscreen") {
    fullscreen = value;
  } else if (keyString == "scrollbars") {
    scrollbarsVisible = value;
  } else if (keyString == "noopener") {
    noopener = true;
  } else if (value == 1) {
    additionalFeatures.append(keyString);
  }
}

WindowFeatures::WindowFeatures(const String& dialogFeaturesString,
                               const IntRect& screenAvailableRect)
    : widthSet(true),
      heightSet(true),
      menuBarVisible(false),
      toolBarVisible(false),
      locationBarVisible(false),
      fullscreen(false),
      dialog(true),
      noopener(false) {
  DialogFeaturesMap features;
  parseDialogFeatures(dialogFeaturesString, features);

  const bool trusted = false;

  // The following features from Microsoft's documentation are not implemented:
  // - default font settings
  // - width, height, left, and top specified in units other than "px"
  // - edge (sunken or raised, default is raised)
  // - dialogHide: trusted && boolFeature(features, "dialoghide"), makes dialog
  //               hide when you print
  // - help: boolFeature(features, "help", true), makes help icon appear in
  //         dialog (what does it do on Windows?)
  // - unadorned: trusted && boolFeature(features, "unadorned");

  // default here came from frame size of dialog in MacIE
  width = intFeature(features, "dialogwidth", 100, screenAvailableRect.width(),
                     620);
  // default here came from frame size of dialog in MacIE
  height = intFeature(features, "dialogheight", 100,
                      screenAvailableRect.height(), 450);

  x = intFeature(features, "dialogleft", screenAvailableRect.x(),
                 screenAvailableRect.maxX() - width, -1);
  xSet = x > 0;
  y = intFeature(features, "dialogtop", screenAvailableRect.y(),
                 screenAvailableRect.maxY() - height, -1);
  ySet = y > 0;

  if (boolFeature(features, "center", true)) {
    if (!xSet) {
      x = screenAvailableRect.x() + (screenAvailableRect.width() - width) / 2;
      xSet = true;
    }
    if (!ySet) {
      y = screenAvailableRect.y() + (screenAvailableRect.height() - height) / 2;
      ySet = true;
    }
  }

  resizable = boolFeature(features, "resizable");
  scrollbarsVisible = boolFeature(features, "scroll", true);
  statusBarVisible = boolFeature(features, "status", !trusted);
}

bool WindowFeatures::boolFeature(const DialogFeaturesMap& features,
                                 const char* key,
                                 bool defaultValue) {
  DialogFeaturesMap::const_iterator it = features.find(key);
  if (it == features.end())
    return defaultValue;
  const String& value = it->value;
  return value.isNull() || value == "1" || value == "yes" || value == "on";
}

int WindowFeatures::intFeature(const DialogFeaturesMap& features,
                               const char* key,
                               int min,
                               int max,
                               int defaultValue) {
  DialogFeaturesMap::const_iterator it = features.find(key);
  if (it == features.end())
    return defaultValue;
  bool ok;
  int parsedNumber = it->value.toInt(&ok);
  if (!ok)
    return defaultValue;
  if (parsedNumber < min || max <= min)
    return min;
  if (parsedNumber > max)
    return max;
  return parsedNumber;
}

void WindowFeatures::parseDialogFeatures(const String& string,
                                         DialogFeaturesMap& map) {
  Vector<String> vector;
  string.split(';', vector);
  size_t size = vector.size();
  for (size_t i = 0; i < size; ++i) {
    const String& featureString = vector[i];

    size_t separatorPosition = featureString.find('=');
    size_t colonPosition = featureString.find(':');
    if (separatorPosition != kNotFound && colonPosition != kNotFound)
      continue;  // ignore strings that have both = and :
    if (separatorPosition == kNotFound)
      separatorPosition = colonPosition;

    String key =
        featureString.left(separatorPosition).stripWhiteSpace().lower();

    // Null string for value indicates key without value.
    String value;
    if (separatorPosition != kNotFound) {
      value = featureString.substring(separatorPosition + 1)
                  .stripWhiteSpace()
                  .lower();
      value = value.left(value.find(' '));
    }

    map.set(key, value);
  }
}

}  // namespace blink
