// Copyright 2016 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/renderer/rasterizer/skia/skia/src/ports/SkFontConfigParser_cobalt.h"

#include <libxml/parser.h>
#include <limits>
#include <memory>
#include <stack>
#include <string>

#include "SkData.h"
#include "SkOSFile.h"
#include "SkOSPath.h"
#include "SkStream.h"
#include "SkTSearch.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"

namespace {

const char* kConfigFile = "fonts.xml";

/////////////////////////////////////////////////////////////////////////////
// Helpers
/////////////////////////////////////////////////////////////////////////////

std::string StringPrintVAndTrim(const char* message, va_list arguments) {
  const std::string formatted_message = base::StringPrintV(message, arguments);

  std::string trimmed_message;
  base::TrimWhitespaceASCII(formatted_message, base::TRIM_ALL,
                            &trimmed_message);

  return trimmed_message;
}

// https://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-negative-def
template <typename T>
bool ParseNonNegativeInteger(const char* s, T* value) {
  static_assert(std::numeric_limits<T>::is_integer, "T must be integer");
  const T n_max = std::numeric_limits<T>::max() / 10;
  const T d_max = std::numeric_limits<T>::max() - (n_max * 10);
  T n = 0;
  for (; *s; ++s) {
    // Check if digit
    if (!base::IsAsciiDigit(*s)) {
      return false;
    }
    int d = *s - '0';
    // Check for overflow
    if (n > n_max || (n == n_max && d > d_max)) {
      LOG(ERROR) << "---- ParseNonNegativeInteger error: overflow";
      return false;
    }
    n = (n * 10) + d;
  }
  *value = n;
  return true;
}

template <typename T>
bool ParseInteger(const char* s, T* value) {
  static_assert(std::numeric_limits<T>::is_signed, "T must be signed");
  T multiplier = 1;
  if (*s && *s == '-') {
    multiplier = -1;
    ++s;
  }
  if (!ParseNonNegativeInteger(s, value)) {
    return false;
  }
  *value *= multiplier;
  return true;
}

template <typename T>
bool ParseFontWeight(const char* s, T* value) {
  T n = 0;
  if (!ParseNonNegativeInteger(s, &n)) {
    return false;
  }
  // Verify that the weight is a multiple of 100 between 100 and 900.
  // https://www.w3.org/TR/css-fonts-3/#font-weight-prop
  if (n < 100 || n > 900 || n % 100 != 0) {
    return false;
  }
  *value = n;
  return true;
}

// The page range list is a comma-delimited list of character page ranges. Each
// page range can either consist of either a single integer value, or a pair of
// values separated by a hyphen (representing the min and max value of the
// range). All page values must fall between 0 and kMaxPageValue. Additionally,
// the page ranges must be provided in ascending order. Any failure to meet
// these expectations will result in a parsing error.
bool ParsePageRangeList(const char* s, font_character_map::PageRanges* ranges) {
  const int16 n_max = font_character_map::kMaxPageValue / 10;
  const int16 d_max = font_character_map::kMaxPageValue - (n_max * 10);

  int16 last_max = -1;

  while (*s) {
    font_character_map::PageRange range_value;

    // Skip whitespace
    while (base::IsAsciiWhitespace(*s)) {
      ++s;
      if (!*s) {
        return true;
      }
    }

    for (int i = 0; i <= 1; ++i) {
      if (!base::IsAsciiDigit(*s)) {
        LOG(ERROR)
            << "---- ParsePageRangeList error: non-ascii digit page range";
        return false;
      }

      int16 n = 0;
      for (; *s; ++s) {
        if (!base::IsAsciiDigit(*s)) {
          break;
        }
        int d = *s - '0';
        // Check for overflow
        if (n > n_max || (n == n_max && d > d_max)) {
          LOG(ERROR) << "---- ParsePageRangeList error: page range overflow";
          return false;
        }

        n = (n * 10) + d;
      }

      if (i == 0) {
        // Verify that this new range is larger than the previously encountered
        // max. Ranges must appear in order. If it isn't, then the parsing has
        // failed.
        if (last_max >= n) {
          LOG(ERROR) << "---- ParsePageRangeList error: pages unordered";
          return false;
        }

        range_value.first = n;

        if (*s && *s == '-') {
          ++s;
          continue;
        } else {
          last_max = n;
          range_value.second = n;
          ranges->push_back(range_value);
          break;
        }
      } else {
        if (range_value.first <= n) {
          last_max = n;
          range_value.second = n;
          ranges->push_back(range_value);
        } else {
          LOG(ERROR) << "---- ParsePageRangeList error: page range flipped";
          return false;
        }
      }
    }

    if (*s) {
      // Skip whitespace
      while (base::IsAsciiWhitespace(*s)) {
        ++s;
        if (!*s) {
          return true;
        }
      }

      if (*s == ',') {
        ++s;
      } else {
        LOG(ERROR) << "---- ParsePageRangeList error: invalid character";
        return false;
      }
    }
  }

  return true;
}

/////////////////////////////////////////////////////////////////////////////
// Libxml SAX Handlers
/////////////////////////////////////////////////////////////////////////////

typedef unsigned char xmlChar;

void StartElement(void* context, const xmlChar* name,
                  const xmlChar** attribute_pairs);
void EndElement(void* context, const xmlChar* name);
void Characters(void* context, const xmlChar* ch, int len);
void ParserWarning(void* context, const char* message, ...);
void ParserError(void* context, const char* message, ...);
void ParserFatal(void* context, const char* message, ...);

xmlSAXHandler xml_sax_handler = {
    NULL,           /* internalSubset */
    NULL,           /* isStandalone */
    NULL,           /* hasInternalSubset */
    NULL,           /* hasExternalSubset */
    NULL,           /* resolveEntity */
    NULL,           /* getEntity */
    NULL,           /* entityDecl */
    NULL,           /* notationDecl */
    NULL,           /* attributeDecl */
    NULL,           /* elementDecl */
    NULL,           /* unparsedEntityDecl */
    NULL,           /* setDocumentLocator */
    NULL,           /* startDocument */
    NULL,           /* endDocument */
    &StartElement,  /* startElement */
    &EndElement,    /* endElement */
    NULL,           /* reference */
    &Characters,    /* characters */
    NULL,           /* ignorableWhitespace */
    NULL,           /* processingInstruction */
    NULL,           /* comment */
    &ParserWarning, /* xmlParserWarning */
    &ParserError,   /* xmlParserError */
    &ParserFatal,   /* xmlParserFatalError */
    NULL,           /* getParameterEntity */
    NULL,           /* cdataBlock */
    NULL,           /* externalSubset */
    1,              /* initialized */
    NULL,           /* private */
    NULL,           /* startElementNsSAX2Func */
    NULL,           /* endElementNsSAX2Func */
    NULL            /* xmlStructuredErrorFunc */
};

enum ElementType {
  kFamilyElementType,
  kFontElementType,
  kAliasElementType,
  kOtherElementType,
};

// The ParserContext structure is passed around by the parser so that each
// handler can read these variables that are relevant to the current parsing.
struct ParserContext {
  explicit ParserContext(SkTDArray<FontFamilyInfo*>* families_array)
      : families(families_array), current_font_info(NULL) {}

  // The array that each family is put into as it is parsed
  SkTDArray<FontFamilyInfo*>* families;
  // The current family being created. FamilyData owns this object while it is
  // not NULL.
  std::unique_ptr<FontFamilyInfo> current_family;
  // The current FontFileInfo being created. It is owned by FontFamilyInfo.
  FontFileInfo* current_font_info;

  // Contains all of the elements that are actively being parsed.
  std::stack<ElementType> element_stack;
};

void FamilyElementHandler(FontFamilyInfo* family, const char** attributes) {
  if (attributes == NULL) {
    return;
  }

  // A <family> may have the following attributes:
  // name (string), fallback_priority (int), lang (string), pages (comma
  // delimited int ranges)
  // A <family> tag must have a canonical name attribute or be a fallback
  // family in order to be usable, unless it is the default family.
  // A family is a fallback family if one of two conditions are met:
  //   1. It does not have a "name" attribute.
  //   2. It has a "fallback_priority" attribute.
  // If the fallback_priority attribute exists, then the family is given the
  // fallback priority specified by the value. If it does not exist, then the
  // fallback priority defaults to 0.
  // The lang and pages attributes are only used by fallback families.

  bool encountered_fallback_attribute = false;
  family->is_fallback_family = true;

  for (size_t i = 0; attributes[i] != NULL && attributes[i + 1] != NULL;
       i += 2) {
    const char* name = attributes[i];
    const char* value = attributes[i + 1];
    size_t name_len = strlen(name);

    if (name_len == 4 && strncmp(name, "name", name_len) == 0) {
      SkAutoAsciiToLC to_lowercase(value);
      family->names.push_back().set(to_lowercase.lc());
      // As long as no fallback attribute is encountered, then the existence of
      // a name attribute removes this family from fallback.
      if (!encountered_fallback_attribute) {
        family->is_fallback_family = false;
      }
    } else if (name_len == 4 && strncmp("lang", name, name_len) == 0) {
      family->language = SkLanguage(value);
    } else if (name_len == 5 && strncmp("pages", name, name_len) == 0) {
      if (!ParsePageRangeList(value, &family->page_ranges)) {
        LOG(ERROR) << "---- Invalid page ranges [" << value << "]";
        NOTREACHED();
        family->page_ranges.reset();
      }
    } else if (name_len == 17 &&
               strncmp("fallback_priority", name, name_len) == 0) {
      encountered_fallback_attribute = true;
      if (!ParseInteger(value, &family->fallback_priority)) {
        LOG(ERROR) << "---- Invalid fallback priority [" << value << "]";
        NOTREACHED();
      }
    } else {
      LOG(ERROR) << "---- Unsupported family attribute [" << name << "]";
      NOTREACHED();
    }
  }
}

void FontElementHandler(FontFileInfo* file, const char** attributes) {
  DCHECK(file != NULL);

  // A <font> may have following attributes:
  // weight (non-negative integer), style (normal, italic), font_name (string),
  // postscript_name (string), and index (non-negative integer)
  // The element should contain a filename.

  for (size_t i = 0; attributes[i] != NULL && attributes[i + 1] != NULL;
       i += 2) {
    const char* name = attributes[i];
    const char* value = attributes[i + 1];

    switch (strlen(name)) {
      case 5:
        if (strncmp("index", name, 5) == 0) {
          if (!ParseNonNegativeInteger(value, &file->index)) {
            LOG(ERROR) << "---- Invalid font index [" << value << "]";
            NOTREACHED();
          }
          continue;
        } else if (strncmp("style", name, 5) == 0) {
          if (strncmp("italic", value, 6) == 0) {
            file->style = FontFileInfo::kItalic_FontStyle;
            continue;
          } else if (strncmp("normal", value, 6) == 0) {
            file->style = FontFileInfo::kNormal_FontStyle;
            continue;
          } else {
            LOG(ERROR) << "---- Unsupported style [" << value << "]";
            NOTREACHED();
          }
        }
        break;
      case 6:
        if (strncmp("weight", name, 6) == 0) {
          if (!ParseFontWeight(value, &file->weight)) {
            LOG(ERROR) << "---- Invalid font weight [" << value << "]";
            NOTREACHED();
          }
          continue;
        }
        break;
      case 9:
        if (strncmp("font_name", name, 9) == 0) {
          SkAutoAsciiToLC to_lowercase(value);
          file->full_font_name = to_lowercase.lc();
          continue;
        }
        break;
      case 15:
        if (strncmp("postscript_name", name, 15) == 0) {
          SkAutoAsciiToLC to_lowercase(value);
          file->postscript_name = to_lowercase.lc();
          continue;
        }
        break;
      case 25:
        if (strncmp("disable_synthetic_bolding", name, 25) == 0) {
          file->disable_synthetic_bolding =
              strcmp("true", value) == 0 || strcmp("1", value) == 0;
          continue;
        }
        break;
      default:
        break;
    }
  }
}

FontFamilyInfo* FindFamily(ParserContext* context, const char* family_name) {
  size_t name_len = strlen(family_name);
  for (int i = 0; i < context->families->count(); i++) {
    FontFamilyInfo* candidate = (*context->families)[i];
    for (int j = 0; j < candidate->names.count(); j++) {
      if (!strncmp(candidate->names[j].c_str(), family_name, name_len) &&
          name_len == strlen(candidate->names[j].c_str())) {
        return candidate;
      }
    }
  }

  return NULL;
}

void AliasElementHandler(ParserContext* context, const char** attributes) {
  // An <alias> must have name and to attributes.
  // It is a variant name for a <family>.

  SkString alias_name;
  SkString to;
  for (size_t i = 0; attributes[i] != NULL && attributes[i + 1] != NULL;
       i += 2) {
    const char* name = attributes[i];
    const char* value = attributes[i + 1];
    size_t name_len = strlen(name);
    if (name_len == 4 && strncmp("name", name, name_len) == 0) {
      SkAutoAsciiToLC to_lowercase(value);
      alias_name.set(to_lowercase.lc());
    } else if (name_len == 2 && strncmp("to", name, name_len) == 0) {
      to.set(value);
    }
  }

  // Assumes that the named family is already declared
  FontFamilyInfo* target_family = FindFamily(context, to.c_str());
  if (!target_family) {
    LOG(ERROR) << "---- Invalid alias target [name: " << alias_name.c_str()
               << ", to: " << to.c_str() << "]";
    NOTREACHED();
    return;
  } else if (alias_name.size() == 0) {
    LOG(ERROR) << "---- Invalid alias name [to: " << to.c_str() << "]";
    NOTREACHED();
    return;
  }

  target_family->names.push_back().set(alias_name);
}

void StartElement(void* context, const xmlChar* xml_tag,
                  const xmlChar** xml_attribute_pairs) {
  ParserContext* parser_context = reinterpret_cast<ParserContext*>(context);
  const char* tag = reinterpret_cast<const char*>(xml_tag);
  const char** attribute_pairs =
      reinterpret_cast<const char**>(xml_attribute_pairs);
  size_t tag_len = strlen(tag);

  if (tag_len == 6 && strncmp("family", tag, tag_len) == 0) {
    parser_context->element_stack.push(kFamilyElementType);
    parser_context->current_family = base::WrapUnique(new FontFamilyInfo());
    FamilyElementHandler(parser_context->current_family.get(), attribute_pairs);
  } else if (tag_len == 4 && strncmp("font", tag, tag_len) == 0) {
    parser_context->element_stack.push(kFontElementType);
    FontFileInfo* file = &parser_context->current_family->fonts.push_back();
    parser_context->current_font_info = file;
    FontElementHandler(file, attribute_pairs);
  } else if (tag_len == 5 && strncmp("alias", tag, tag_len) == 0) {
    parser_context->element_stack.push(kAliasElementType);
    AliasElementHandler(parser_context, attribute_pairs);
  } else {
    parser_context->element_stack.push(kOtherElementType);
  }
}

void EndElement(void* context, const xmlChar* xml_tag) {
  ParserContext* parser_context = reinterpret_cast<ParserContext*>(context);
  const char* tag = reinterpret_cast<const char*>(xml_tag);
  size_t tag_len = strlen(tag);

  if (tag_len == 6 && strncmp("family", tag, tag_len) == 0) {
    if (parser_context->current_family != NULL) {
      *parser_context->families->append() =
          parser_context->current_family.release();
    } else {
      LOG(ERROR) << "---- Encountered end family tag with no current family";
      NOTREACHED();
    }
  }

  parser_context->element_stack.pop();
}

void Characters(void* context, const xmlChar* xml_characters, int len) {
  ParserContext* parser_context = reinterpret_cast<ParserContext*>(context);
  const char* characters = reinterpret_cast<const char*>(xml_characters);

  if (parser_context->element_stack.size() > 0 &&
      parser_context->element_stack.top() == kFontElementType) {
    parser_context->current_font_info->file_name.set(characters, len);
  }
}

void ParserWarning(void* context, const char* message, ...) {
  va_list arguments;
  va_start(arguments, message);

  DLOG(WARNING) << "---- Parsing warning: "
                << StringPrintVAndTrim(message, arguments).c_str();
}

void ParserError(void* context, const char* message, ...) {
  va_list arguments;
  va_start(arguments, message);

  LOG(ERROR) << "---- Parsing error: "
             << StringPrintVAndTrim(message, arguments).c_str();
  NOTREACHED();
}

void ParserFatal(void* context, const char* message, ...) {
  va_list arguments;
  va_start(arguments, message);

  LOG(ERROR) << "---- Parsing fatal error: "
             << StringPrintVAndTrim(message, arguments).c_str();
  NOTREACHED();
}

// This function parses the given filename and stores the results in the given
// families array.
void ParseConfigFile(const char* directory,
                     SkTDArray<FontFamilyInfo*>* families) {
  SkString file_path = SkOSPath::Join(directory, kConfigFile);

  std::unique_ptr<SkStream> file_stream(
      SkStream::MakeFromFile(file_path.c_str()));
  if (file_stream == NULL) {
    LOG(ERROR) << "---- Failed to open " << file_path.c_str();
    return;
  }

  sk_sp<SkData> file_data(
      SkData::MakeFromStream(file_stream.get(), file_stream->getLength()));
  if (file_data == NULL) {
    LOG(ERROR) << "---- Failed to read " << file_path.c_str();
    return;
  }

  ParserContext parser_context(families);
  int return_value =
      xmlSAXUserParseMemory(&xml_sax_handler, &parser_context,
                            static_cast<const char*>(file_data->data()),
                            static_cast<int>(file_data->size()));
  DCHECK_EQ(return_value, 0);
}

}  // namespace

namespace SkFontConfigParser {

// Loads data on font families from the configuration file. The resulting data
// is returned in the given fontFamilies array.
void GetFontFamilies(const char* directory,
                     SkTDArray<FontFamilyInfo*>* font_families) {
  ParseConfigFile(directory, font_families);
}

}  // namespace SkFontConfigParser
