// 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 if (name_len == 15 &&
               strncmp("disable_caching", name, name_len) == 0) {
      family->disable_caching =
          strcmp("true", value) == 0 || strcmp("1", value) == 0;
    } 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
