// Copyright 2019 The Cobalt Authors. 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/cssom/serializer.h"

#include "cobalt/cssom/active_pseudo_class.h"
#include "cobalt/cssom/after_pseudo_element.h"
#include "cobalt/cssom/attribute_selector.h"
#include "cobalt/cssom/before_pseudo_element.h"
#include "cobalt/cssom/class_selector.h"
#include "cobalt/cssom/complex_selector.h"
#include "cobalt/cssom/compound_selector.h"
#include "cobalt/cssom/empty_pseudo_class.h"
#include "cobalt/cssom/focus_pseudo_class.h"
#include "cobalt/cssom/hover_pseudo_class.h"
#include "cobalt/cssom/id_selector.h"
#include "cobalt/cssom/not_pseudo_class.h"
#include "cobalt/cssom/simple_selector.h"
#include "cobalt/cssom/type_selector.h"

namespace cobalt {
namespace cssom {

namespace {
// Used to replace an unknown, unrecognized or unrepresentable character.
constexpr int kUnicodeReplacementCharacter = 0xFFFD;
constexpr char kUnicodeReplacementCharacterUtf8[] = u8"\uFFFD";
}  // namespace

Serializer::Serializer(std::string* output) : output_(output) {}

void Serializer::SerializeIdentifier(base::Token identifier) {
  // https://www.w3.org/TR/cssom/#serialize-an-identifier
  //
  // To serialize an identifier means to create a string represented by the
  // concatenation of, for each character of the identifier: For each character
  // of the identifier:
  int char_num = 0;
  uint32_t first_char = 0;
  const uint8_t* next_p = reinterpret_cast<const uint8_t*>(identifier.c_str());
  while (*next_p) {
    uint32_t c;  // code point
    const uint8_t* curr_p = next_p;
    next_p += DecodeUTF8(curr_p, &c);

    char_num++;
    if (char_num == 1) first_char = c;

    // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
    // (U+FFFD).
    if (c == 0x00) {
      output_->append(kUnicodeReplacementCharacterUtf8);
      continue;
    }

    // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is
    // U+007F, then the character escaped as code point.
    if ((0x01 <= c && c <= 0x1F) || c == 0x7f) {
      EscapeCodePoint(c);
      continue;
    }

    // If the character is the first character and is in the range [0-9] (U+0030
    // to U+0039), then the character escaped as code point.
    bool is_numeric = ('0' <= c && c <= '9');
    if (char_num == 1 && is_numeric) {
      EscapeCodePoint(c);
      continue;
    }

    // If the character is the second character and is in the range [0-9]
    // (U+0030 to U+0039) and the first character is a "-" (U+002D), then the
    // character escaped as code point.
    if (char_num == 2 && is_numeric && first_char == '-') {
      EscapeCodePoint(c);
      continue;
    }

    // If the character is the first character and is a "-" (U+002D), and there
    // is no second character, then the escaped character.
    if (char_num == 1 && c == '-' && *next_p == '\0') {
      EscapeCharacter(c);
      continue;
    }

    // If the character is not handled by one of the above rules and is greater
    // than or equal to U+0080, is "-" (U+002D) or "_" (U+005F), or is in one of
    // the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to U+005A), or \[a-z]
    // (U+0061 to U+007A), then the character itself.
    if (c >= 0x80 || c == '-' || c == '_' || is_numeric ||
        ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) {
      do {
        output_->push_back(*curr_p);
      } while (++curr_p < next_p);
      continue;
    }

    // Otherwise, the escaped character.
    EscapeCharacter(c);
  }
}

void Serializer::SerializeString(const std::string& string) {
  // https://www.w3.org/TR/cssom/#serialize-a-string
  //
  // Create a string represented by '"' (U+0022), followed by the result of
  // applying the rules below to each character of the given string, followed by
  // '"' (U+0022):
  output_->push_back('"');

  const uint8_t* p = reinterpret_cast<const uint8_t*>(string.c_str());
  for (size_t n = 0, length = string.length(); n < length; ++n) {
    uint8_t c = p[n];

    // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER
    // (U+FFFD) escaped as code point.
    if (c == 0x00) {
      EscapeCodePoint(kUnicodeReplacementCharacter);
      continue;
    }

    // If the character is in the range [\1-\1f] (U+0001 to U+001F) or is
    // U+007F, the character escaped as code point.
    if ((0x01 <= c && c <= 0x1F) || c == 0x7f) {
      EscapeCodePoint(c);
      continue;
    }

    // If the character is '"' (U+0022) or "\" (U+005C), the escaped character.
    if (c == 0x22 || c == 0x5c) {
      EscapeCharacter(c);
      continue;
    }

    // Otherwise, the character itself.
    output_->push_back(c);
  }

  // ...followed by '"' (U+0022)
  output_->push_back('"');
}

void Serializer::SerializeSelectors(const Selectors& selectors) {
  // https://www.w3.org/TR/cssom/#serializing-selectors
  //
  // To serialize a group of selectors serialize each selector in the group of
  // selectors and then serialize the group.
  for (auto it = selectors.begin(); it != selectors.end(); it++) {
    // https://www.w3.org/TR/cssom/#serialize-a-comma-separated-list
    //
    // To serialize a comma-separated list concatenate all items of the list in
    // list order while separating them by ", ", i.e., COMMA (U+002C) followed
    // by a single SPACE (U+0020).
    if (it != selectors.begin()) {
      output_->append(", ");
    }
    SerializeSelector(**it);
  }
}

void Serializer::SerializeSelector(const Selector& selector) {
  const_cast<Selector*>(&selector)->Accept(this);
}

int Serializer::DecodeUTF8(const uint8_t* p, uint32_t* out_c) {
  DCHECK(p && *p);
  uint32_t c;
  int len;
  if (p[0] < 0x80) {
    *out_c = p[0];
    return 1;
  } else if (p[0] < 0xC0) {
    DLOG(ERROR) << "Bad UTF-8 first byte";
    *out_c = kUnicodeReplacementCharacter;
    return 1;
  } else if (p[0] < 0xE0) {
    c = p[0] & 0x1F;
    len = 2;
  } else if (p[0] < 0xF0) {
    c = p[0] & 0x0F;
    len = 3;
  } else if (p[0] < 0xF8) {
    c = p[0] & 0x07;
    len = 4;
  } else {
    DLOG(ERROR) << "Bad UTF-8 first byte";
    *out_c = kUnicodeReplacementCharacter;
    return 1;
  }
  for (int n = 1; n < len; ++n) {
    if ((p[n] & 0xC0) != 0x80) {
      DLOG(ERROR) << "Bad UTF-8 byte " << n;
      *out_c = kUnicodeReplacementCharacter;
      return n;
    }
    c <<= 6;
    c |= p[n] & 0x3F;
  }
  *out_c = c;
  return len;
}

void Serializer::EscapeCodePoint(uint32_t c) {
  // Highest valid code point in Unicode.
  DCHECK_LE(c, 0x10FFFFu);

  // To escape a character as code point means to create a string of "\"
  // (U+005C), followed by the Unicode code point as the smallest possible
  // number of hexadecimal digits in the range 0-9 a-f (U+0030 to U+0039 and
  // U+0061 to U+0066) to represent the code point in base 16, followed by a
  // single SPACE (U+0020).
  output_->push_back('\\');

  constexpr char kHexDigits[] = "0123456789abcdef";
  char buffer[9];
  int pos = sizeof(buffer);
  buffer[--pos] = '\0';
  while (c != 0) {
    buffer[--pos] = kHexDigits[c & 0x0F];
    c >>= 4;
  }
  if (pos + 1 == sizeof(buffer)) buffer[--pos] = '0';
  output_->append(buffer + pos);

  // ...followed by a single SPACE (U+0020).
  output_->push_back(' ');
}

void Serializer::EscapeCharacter(uint32_t c) {
  // To escape a character means to create a string of "\" (U+005C), followed by
  // the character.
  DCHECK_GE(c, 0x20u);
  DCHECK_LE(c, 0x7Fu);
  output_->push_back('\\');
  output_->push_back(static_cast<char>(c));
}

void Serializer::VisitUniversalSelector(UniversalSelector* universal_selector) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  // If this is a universal selector append "*" (U+002A) to s.
  output_->push_back('*');
}

void Serializer::VisitTypeSelector(TypeSelector* type_selector) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  // If this is a type selector append the escaped element name to s.
  SerializeIdentifier(type_selector->element_name());
}

void Serializer::VisitAttributeSelector(AttributeSelector* attribute_selector) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector

  // 1. Append "[" (U+005B) to s.
  output_->push_back('[');

  // 2. If the namespace prefix maps to a namespace that is not the null
  // namespace (not in a namespace) append the escaped namespace prefix,
  // followed by a "|" (U+007C) to s.
  // [Cobalt doesn't support @namespace]

  // 3. Append the escaped attribute name to s.
  SerializeIdentifier(attribute_selector->attribute_name());

  // 4. If there is an attribute value specified, append "=", "~=", "|=", "^=",
  // "$=", or "*=" as appropriate (depending on the type of attribute selector),
  // followed by the string escaped attribute value, to s.
  const char* match_op = nullptr;
  switch (attribute_selector->value_match_type()) {
    case AttributeSelector::kNoMatch:
      match_op = nullptr;
      break;
    case AttributeSelector::kEquals:
      match_op = "=";
      break;
    case AttributeSelector::kIncludes:
      match_op = "~=";
      break;
    case AttributeSelector::kDashMatch:
      match_op = "|=";
      break;
    case AttributeSelector::kBeginsWith:
      match_op = "^=";
      break;
    case AttributeSelector::kEndsWith:
      match_op = "$=";
      break;
    case AttributeSelector::kContains:
      match_op = "*=";
      break;
  }
  if (match_op != nullptr) {
    output_->append(match_op);
    SerializeString(attribute_selector->attribute_value());
  }

  // 5. If the attribute selector has the case-sensitivity flag present, append
  // " i" (U+0020 U+0069) to s.
  // [Cobalt doesn't support the CSS4 case-sensitivity attributes.]

  // 6. Append "]" (U+005D) to s.
  output_->push_back(']');
}

void Serializer::VisitClassSelector(ClassSelector* class_selector) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  // Append a "." (U+002E), followed by the escaped class name to s.
  output_->push_back('.');
  SerializeIdentifier(class_selector->class_name());
}

void Serializer::VisitIdSelector(IdSelector* id_selector) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  // Append a "#" (U+0023), followed by the escaped ID to s.
  output_->push_back('#');
  SerializeIdentifier(id_selector->id());
}

void Serializer::VisitPseudoClass(PseudoClass* pseudo_class) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  // If the pseudo-class does not accept arguments append ":" (U+003A),
  // followed by the name of the pseudo-class, to s.
  output_->push_back(':');
  output_->append(pseudo_class->text().c_str());
}

void Serializer::VisitActivePseudoClass(
    ActivePseudoClass* active_pseudo_class) {
  VisitPseudoClass(active_pseudo_class);
}

void Serializer::VisitEmptyPseudoClass(EmptyPseudoClass* empty_pseudo_class) {
  VisitPseudoClass(empty_pseudo_class);
}

void Serializer::VisitFocusPseudoClass(FocusPseudoClass* focus_pseudo_class) {
  VisitPseudoClass(focus_pseudo_class);
}

void Serializer::VisitHoverPseudoClass(HoverPseudoClass* hover_pseudo_class) {
  VisitPseudoClass(hover_pseudo_class);
}

void Serializer::VisitNotPseudoClass(NotPseudoClass* not_pseudo_class) {
  // https://www.w3.org/TR/cssom/#serialize-a-simple-selector
  //
  // Append ":" (U+003A), followed by the name of the pseudo-class, followed by
  // "(" (U+0028), followed by the value of the pseudo-class argument(s)
  // determined as per below, followed by ")" (U+0029), to s.
  // ...
  // :not() - The result of serializing the value using the rules for
  // serializing a group of selectors.
  VisitPseudoClass(not_pseudo_class);
  output_->push_back('(');
  not_pseudo_class->selector()->Accept(this);
  output_->push_back(')');
}

void Serializer::VisitPseudoElement(PseudoElement* pseudo_element) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  // If this is the last part of the chain of the selector and there is a
  // pseudo-element, append "::" followed by the name of the pseudo-element,
  // to s.
  output_->append("::");
  output_->append(pseudo_element->text().c_str());
}

void Serializer::VisitAfterPseudoElement(
    AfterPseudoElement* after_pseudo_element) {
  VisitPseudoElement(after_pseudo_element);
}

void Serializer::VisitBeforePseudoElement(
    BeforePseudoElement* before_pseudo_element) {
  VisitPseudoElement(before_pseudo_element);
}

void Serializer::VisitCompoundSelector(CompoundSelector* compound_selector) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  //
  // 1. If there is only one simple selector in the compound selectors which is
  // a universal selector, append the result of serializing the universal
  // selector to s.
  if (compound_selector->simple_selectors().size() == 1 &&
      compound_selector->simple_selectors().front()->AsUniversalSelector()) {
    compound_selector->simple_selectors().front()->Accept(this);
    return;
  }

  // 2. Otherwise, for each simple selector in the compound selectors that is
  // not a universal selector of which the namespace prefix maps to a namespace
  // that is not the default namespace serialize the simple selector and append
  // the result to s.
  // [Cobalt doesn't support @namespace]
  for (CompoundSelector::SimpleSelectors::const_iterator iter =
           compound_selector->simple_selectors().begin();
       iter != compound_selector->simple_selectors().end(); ++iter) {
    if ((*iter)->AsUniversalSelector() == NULL) {
      (*iter)->Accept(this);
    }
  }
}

void Serializer::VisitComplexSelector(ComplexSelector* complex_selector) {
  // https://www.w3.org/TR/cssom/#serialize-a-selector
  //
  // If this is not the last part of the chain of the selector append a single
  // SPACE (U+0020), followed by the combinator ">", "+", "~", ">>", "||", as
  // appropriate, followed by another single SPACE (U+0020) if the combinator
  // was not whitespace, to s.
  CompoundSelector* selector = complex_selector->first_selector();
  if (!selector) return;
  selector->Accept(this);
  Combinator* combinator = selector->right_combinator();
  while (combinator) {
    // The |VisitFooCombinator| methods below add the spaces before & after.
    combinator->Accept(this);
    selector = combinator->right_selector();
    selector->Accept(this);
    combinator = selector->right_combinator();
  }
}

void Serializer::VisitChildCombinator(ChildCombinator* child_combinator) {
  output_->append(" > ");
}

void Serializer::VisitNextSiblingCombinator(
    NextSiblingCombinator* next_sibling_combinator) {
  output_->append(" + ");
}

void Serializer::VisitDescendantCombinator(
    DescendantCombinator* descendant_combinator) {
  output_->push_back(' ');
}

void Serializer::VisitFollowingSiblingCombinator(
    FollowingSiblingCombinator* following_sibling_combinator) {
  output_->append(" ~ ");
}

}  // namespace cssom
}  // namespace cobalt
