// 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/dom_string_map.h"

#include "base/string_util.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/global_stats.h"

namespace cobalt {
namespace dom {

namespace {

const char kDataPrefix[] = "data-";
// Subtract one for nul terminator.
const size_t kDataPrefixLength = sizeof(kDataPrefix) - 1;

// See "The algorithm for getting the list of name-value pairs" at
// https://www.w3.org/TR/html5/dom.html#dom-dataset.
base::optional<std::string> TryConvertAttributeNameToPropertyName(
    const std::string& attribute_name) {
  // First five characters of attribute name should be "data-".
  if (attribute_name.compare(0, kDataPrefixLength, kDataPrefix) != 0) {
    return base::nullopt;
  }

  // For each "-" (U+002D) character in the name that is followed by
  // a lowercase ASCII letter, remove the "-" (U+002D) character and replace
  // the character that followed it by the same character converted to ASCII
  // uppercase.
  std::string property_name;
  bool preceded_by_hyphen = false;
  for (std::string::const_iterator attribute_name_iterator =
           attribute_name.begin() + kDataPrefixLength;
       attribute_name_iterator != attribute_name.end();
       ++attribute_name_iterator) {
    char attribute_name_character = *attribute_name_iterator;

    if (attribute_name_character == '-') {
      // Double hyphen in attribute name, preserve it.
      if (preceded_by_hyphen) {
        property_name += '-';
      } else {
        preceded_by_hyphen = true;
      }
      continue;
    }

    // Attribute name should not contain uppercase ASCII characters.
    if (base::ToLowerASCII(attribute_name_character) !=
        attribute_name_character) {
      return base::nullopt;
    }

    // Convert to uppercase character if preceded by hyphen.
    char property_name_character = attribute_name_character;
    if (preceded_by_hyphen) {
      preceded_by_hyphen = false;
      property_name_character = base::ToUpperASCII(property_name_character);

      // Non-letter character after hyphen, preserve the hyphen.
      if (property_name_character == attribute_name_character) {
        property_name += '-';
      }
    }

    property_name += property_name_character;
  }
  if (preceded_by_hyphen) {
    property_name += '-';
  }
  return property_name;
}

// See "The algorithm for setting names to certain values" at
// https://www.w3.org/TR/html5/dom.html#dom-dataset.
base::optional<std::string> TryConvertPropertyNameToAttributeName(
    const std::string& property_name) {
  // Insert the string "data-" at the front of attribute name.
  std::string attribute_name = kDataPrefix;

  bool preceded_by_hyphen = false;
  for (std::string::const_iterator property_name_iterator =
           property_name.begin();
       property_name_iterator != property_name.end();
       ++property_name_iterator) {
    char property_name_character = *property_name_iterator;

    // If property name contains a "-" (U+002D) character followed by
    // a lowercase ASCII letter, abort these steps.
    if (preceded_by_hyphen &&
        base::ToUpperASCII(property_name_character) !=
            property_name_character) {
      return base::nullopt;
    }

    // For each uppercase ASCII letter in name, insert a "-" (U+002D) character
    // before the character and replace the character with the same character
    // converted to ASCII lowercase.
    if (base::ToLowerASCII(property_name_character) !=
        property_name_character) {
      attribute_name += '-';
      attribute_name += base::ToLowerASCII(property_name_character);
    } else {
      attribute_name += property_name_character;
    }

    preceded_by_hyphen = property_name_character == '-';
  }
  return attribute_name;
}

}  // namespace

DOMStringMap::DOMStringMap(const scoped_refptr<Element>& element)
    : element_(element) {
  GlobalStats::GetInstance()->Add(this);
}

base::optional<std::string> DOMStringMap::AnonymousNamedGetter(
    const std::string& property_name, script::ExceptionState* exception_state) {
  base::optional<std::string> attribute_name =
      TryConvertPropertyNameToAttributeName(property_name);
  if (attribute_name) {
    return element_->GetAttribute(*attribute_name);
  } else {
    exception_state->SetSimpleException(script::kSyntaxError,
                                        property_name.c_str());
    return base::nullopt;
  }
}

void DOMStringMap::AnonymousNamedSetter(
    const std::string& property_name, const std::string& value,
    script::ExceptionState* exception_state) {
  base::optional<std::string> attribute_name =
      TryConvertPropertyNameToAttributeName(property_name);
  if (attribute_name) {
    element_->SetAttribute(*attribute_name, value);
  } else {
    exception_state->SetSimpleException(script::kSyntaxError,
                                        property_name.c_str());
  }
}

bool DOMStringMap::CanQueryNamedProperty(
    const std::string& property_name) const {
  base::optional<std::string> attribute_name =
      TryConvertPropertyNameToAttributeName(property_name);
  // TODO: Throw a SyntaxError if attribute name is invalid once getters and
  // setters support throwing exceptions.
  return attribute_name && element_->HasAttribute(*attribute_name);
}

void DOMStringMap::EnumerateNamedProperties(
    script::PropertyEnumerator* enumerator) {
  for (Element::AttributeMap::const_iterator
           attribute_iterator = element_->attribute_map().begin(),
           attribute_end_iterator = element_->attribute_map().end();
       attribute_iterator != attribute_end_iterator; ++attribute_iterator) {
    base::optional<std::string> property_name =
        TryConvertAttributeNameToPropertyName(attribute_iterator->first);
    if (property_name) {
      enumerator->AddProperty(*property_name);
    }
  }
}

DOMStringMap::~DOMStringMap() { GlobalStats::GetInstance()->Remove(this); }

}  // namespace dom
}  // namespace cobalt
