// 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;
    }

    LOG(ERROR) << "---- Unsupported font attribute [" << name << "]";
    NOTREACHED();
  }
}

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
