// Copyright (c) 2009-2017 The OTS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "glat.h"

#include "gloc.h"
#include "lz4.h"
#include <list>

namespace ots {

// -----------------------------------------------------------------------------
// OpenTypeGLAT_v1
// -----------------------------------------------------------------------------

bool OpenTypeGLAT_v1::Parse(const uint8_t* data, size_t length) {
  Buffer table(data, length);
  OpenTypeGLOC* gloc = static_cast<OpenTypeGLOC*>(
      GetFont()->GetTypedTable(OTS_TAG_GLOC));
  if (!gloc) {
    return DropGraphite("Required Gloc table is missing");
  }

  if (!table.ReadU32(&this->version) || this->version >> 16 != 1) {
    return DropGraphite("Failed to read version");
  }

  const std::vector<uint32_t>& locations = gloc->GetLocations();
  if (locations.empty()) {
    return DropGraphite("No locations from Gloc table");
  }
  std::list<uint32_t> unverified(locations.begin(), locations.end());
  while (table.remaining()) {
    GlatEntry entry(this);
    if (table.offset() > unverified.front()) {
      return DropGraphite("Offset check failed for a GlatEntry");
    }
    if (table.offset() == unverified.front()) {
      unverified.pop_front();
    }
    if (unverified.empty()) {
      return DropGraphite("Expected more locations");
    }
    if (!entry.ParsePart(table)) {
      return DropGraphite("Failed to read a GlatEntry");
    }
    this->entries.push_back(entry);
  }

  if (unverified.size() != 1 || unverified.front() != table.offset()) {
    return DropGraphite("%zu location(s) could not be verified", unverified.size());
  }
  if (table.remaining()) {
    return Warning("%zu bytes unparsed", table.remaining());
  }
  return true;
}

bool OpenTypeGLAT_v1::Serialize(OTSStream* out) {
  if (!out->WriteU32(this->version) ||
      !SerializeParts(this->entries, out)) {
    return Error("Failed to write table");
  }
  return true;
}

bool OpenTypeGLAT_v1::GlatEntry::ParsePart(Buffer& table) {
  if (!table.ReadU8(&this->attNum)) {
    return parent->Error("GlatEntry: Failed to read attNum");
  }
  if (!table.ReadU8(&this->num)) {
    return parent->Error("GlatEntry: Failed to read num");
  }

  //this->attributes.resize(this->num);
  for (int i = 0; i < this->num; ++i) {
    this->attributes.emplace_back();
    if (!table.ReadS16(&this->attributes[i])) {
      return parent->Error("GlatEntry: Failed to read attribute %u", i);
    }
  }
  return true;
}

bool OpenTypeGLAT_v1::GlatEntry::SerializePart(OTSStream* out) const {
  if (!out->WriteU8(this->attNum) ||
      !out->WriteU8(this->num) ||
      !SerializeParts(this->attributes, out)) {
    return parent->Error("GlatEntry: Failed to write");
  }
  return true;
}

// -----------------------------------------------------------------------------
// OpenTypeGLAT_v2
// -----------------------------------------------------------------------------

bool OpenTypeGLAT_v2::Parse(const uint8_t* data, size_t length) {
  Buffer table(data, length);
  OpenTypeGLOC* gloc = static_cast<OpenTypeGLOC*>(
      GetFont()->GetTypedTable(OTS_TAG_GLOC));
  if (!gloc) {
    return DropGraphite("Required Gloc table is missing");
  }

  if (!table.ReadU32(&this->version) || this->version >> 16 != 1) {
    return DropGraphite("Failed to read version");
  }

  const std::vector<uint32_t>& locations = gloc->GetLocations();
  if (locations.empty()) {
    return DropGraphite("No locations from Gloc table");
  }
  std::list<uint32_t> unverified(locations.begin(), locations.end());
  while (table.remaining()) {
    GlatEntry entry(this);
    if (table.offset() > unverified.front()) {
      return DropGraphite("Offset check failed for a GlatEntry");
    }
    if (table.offset() == unverified.front()) {
      unverified.pop_front();
    }
    if (unverified.empty()) {
      return DropGraphite("Expected more locations");
    }
    if (!entry.ParsePart(table)) {
      return DropGraphite("Failed to read a GlatEntry");
    }
    this->entries.push_back(entry);
  }

  if (unverified.size() != 1 || unverified.front() != table.offset()) {
    return DropGraphite("%zu location(s) could not be verified", unverified.size());
  }
  if (table.remaining()) {
    return Warning("%zu bytes unparsed", table.remaining());
  }
  return true;
}

bool OpenTypeGLAT_v2::Serialize(OTSStream* out) {
  if (!out->WriteU32(this->version) ||
      !SerializeParts(this->entries, out)) {
    return Error("Failed to write table");
  }
  return true;
}

bool OpenTypeGLAT_v2::GlatEntry::ParsePart(Buffer& table) {
  if (!table.ReadS16(&this->attNum)) {
    return parent->Error("GlatEntry: Failed to read attNum");
  }
  if (!table.ReadS16(&this->num) || this->num < 0) {
    return parent->Error("GlatEntry: Failed to read valid num");
  }

  //this->attributes.resize(this->num);
  for (int i = 0; i < this->num; ++i) {
    this->attributes.emplace_back();
    if (!table.ReadS16(&this->attributes[i])) {
      return parent->Error("GlatEntry: Failed to read attribute %u", i);
    }
  }
  return true;
}

bool OpenTypeGLAT_v2::GlatEntry::SerializePart(OTSStream* out) const {
  if (!out->WriteS16(this->attNum) ||
      !out->WriteS16(this->num) ||
      !SerializeParts(this->attributes, out)) {
    return parent->Error("GlatEntry: Failed to write");
  }
  return true;
}

// -----------------------------------------------------------------------------
// OpenTypeGLAT_v3
// -----------------------------------------------------------------------------

bool OpenTypeGLAT_v3::Parse(const uint8_t* data, size_t length,
                            bool prevent_decompression) {
  Buffer table(data, length);
  OpenTypeGLOC* gloc = static_cast<OpenTypeGLOC*>(
      GetFont()->GetTypedTable(OTS_TAG_GLOC));
  if (!gloc) {
    return DropGraphite("Required Gloc table is missing");
  }

  if (!table.ReadU32(&this->version) || this->version >> 16 != 3) {
    return DropGraphite("Failed to read version");
  }
  if (!table.ReadU32(&this->compHead)) {
    return DropGraphite("Failed to read compression header");
  }
  switch ((this->compHead & SCHEME) >> 27) {
    case 0:  // uncompressed
      break;
    case 1: {  // lz4
      if (prevent_decompression) {
        return DropGraphite("Illegal nested compression");
      }
      std::vector<uint8_t> decompressed(this->compHead & FULL_SIZE);
      int ret = LZ4_decompress_safe_partial(
          reinterpret_cast<const char*>(data + table.offset()),
          reinterpret_cast<char*>(decompressed.data()),
          table.remaining(),  // input buffer size (input size + padding)
          decompressed.size(),  // target output size
          decompressed.size());  // output buffer size
      if (ret != decompressed.size()) {
        return DropGraphite("Decompression failed with error code %d", ret);
      }
      return this->Parse(decompressed.data(), decompressed.size(), true);
    }
    default:
      return DropGraphite("Unknown compression scheme");
  }
  if (this->compHead & RESERVED) {
    Warning("Nonzero reserved");
  }

  const std::vector<uint32_t>& locations = gloc->GetLocations();
  if (locations.empty()) {
    return DropGraphite("No locations from Gloc table");
  }
  std::list<uint32_t> unverified(locations.begin(), locations.end());
  //this->entries.resize(locations.size() - 1, this);
  for (size_t i = 0; i < locations.size() - 1; ++i) {
    this->entries.emplace_back(this);
    if (table.offset() != unverified.front()) {
      return DropGraphite("Offset check failed for a GlyphAttrs");
    }
    unverified.pop_front();
    if (!this->entries[i].ParsePart(table,
                                    unverified.front() - table.offset())) {
        // unverified.front() is guaranteed to exist because of the number of
        // iterations of this loop
      return DropGraphite("Failed to read a GlyphAttrs");
    }
  }

  if (unverified.size() != 1 || unverified.front() != table.offset()) {
    return DropGraphite("%zu location(s) could not be verified", unverified.size());
  }
  if (table.remaining()) {
    return Warning("%zu bytes unparsed", table.remaining());
  }
  return true;
}

bool OpenTypeGLAT_v3::Serialize(OTSStream* out) {
  if (!out->WriteU32(this->version) ||
      !out->WriteU32(this->compHead) ||
      !SerializeParts(this->entries, out)) {
    return Error("Failed to write table");
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::ParsePart(Buffer& table, const size_t size) {
  size_t init_offset = table.offset();
  if (parent->compHead & OCTABOXES && !octabox.ParsePart(table)) {
    // parent->flags & 0b1: octaboxes are present flag
    return parent->Error("GlyphAttrs: Failed to read octabox");
  }

  while (table.offset() < init_offset + size) {
    GlatEntry entry(parent);
    if (!entry.ParsePart(table)) {
      return parent->Error("GlyphAttrs: Failed to read a GlatEntry");
    }
    this->entries.push_back(entry);
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::SerializePart(OTSStream* out) const {
  if ((parent->compHead & OCTABOXES && !octabox.SerializePart(out)) ||
      !SerializeParts(this->entries, out)) {
    return parent->Error("GlyphAttrs: Failed to write");
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::
OctaboxMetrics::ParsePart(Buffer& table) {
  if (!table.ReadU16(&this->subbox_bitmap)) {
    return parent->Error("OctaboxMetrics: Failed to read subbox_bitmap");
  }
  if (!table.ReadU8(&this->diag_neg_min)) {
    return parent->Error("OctaboxMetrics: Failed to read diag_neg_min");
  }
  if (!table.ReadU8(&this->diag_neg_max) ||
      this->diag_neg_max < this->diag_neg_min) {
    return parent->Error("OctaboxMetrics: Failed to read valid diag_neg_max");
  }
  if (!table.ReadU8(&this->diag_pos_min)) {
    return parent->Error("OctaboxMetrics: Failed to read diag_pos_min");
  }
  if (!table.ReadU8(&this->diag_pos_max) ||
      this->diag_pos_max < this->diag_pos_min) {
    return parent->Error("OctaboxMetrics: Failed to read valid diag_pos_max");
  }

  unsigned subboxes_len = 0;  // count of 1's in this->subbox_bitmap
  for (uint16_t i = this->subbox_bitmap; i; i >>= 1) {
    if (i & 0b1) {
      ++subboxes_len;
    }
  }
  //this->subboxes.resize(subboxes_len, parent);
  for (unsigned i = 0; i < subboxes_len; i++) {
    this->subboxes.emplace_back(parent);
    if (!this->subboxes[i].ParsePart(table)) {
      return parent->Error("OctaboxMetrics: Failed to read subbox[%u]", i);
    }
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::
OctaboxMetrics::SerializePart(OTSStream* out) const {
  if (!out->WriteU16(this->subbox_bitmap) ||
      !out->WriteU8(this->diag_neg_min) ||
      !out->WriteU8(this->diag_neg_max) ||
      !out->WriteU8(this->diag_pos_min) ||
      !out->WriteU8(this->diag_pos_max) ||
      !SerializeParts(this->subboxes, out)) {
    return parent->Error("OctaboxMetrics: Failed to write");
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::OctaboxMetrics::
SubboxEntry::ParsePart(Buffer& table) {
  if (!table.ReadU8(&this->left)) {
    return parent->Error("SubboxEntry: Failed to read left");
  }
  if (!table.ReadU8(&this->right) || this->right < this->left) {
    return parent->Error("SubboxEntry: Failed to read valid right");
  }
  if (!table.ReadU8(&this->bottom)) {
    return parent->Error("SubboxEntry: Failed to read bottom");
  }
  if (!table.ReadU8(&this->top) || this->top < this->bottom) {
    return parent->Error("SubboxEntry: Failed to read valid top");
  }
  if (!table.ReadU8(&this->diag_pos_min)) {
    return parent->Error("SubboxEntry: Failed to read diag_pos_min");
  }
  if (!table.ReadU8(&this->diag_pos_max) ||
      this->diag_pos_max < this->diag_pos_min) {
    return parent->Error("SubboxEntry: Failed to read valid diag_pos_max");
  }
  if (!table.ReadU8(&this->diag_neg_min)) {
    return parent->Error("SubboxEntry: Failed to read diag_neg_min");
  }
  if (!table.ReadU8(&this->diag_neg_max) ||
      this->diag_neg_max < this->diag_neg_min) {
    return parent->Error("SubboxEntry: Failed to read valid diag_neg_max");
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::OctaboxMetrics::
SubboxEntry::SerializePart(OTSStream* out) const {
  if (!out->WriteU8(this->left) ||
      !out->WriteU8(this->right) ||
      !out->WriteU8(this->bottom) ||
      !out->WriteU8(this->top) ||
      !out->WriteU8(this->diag_pos_min) ||
      !out->WriteU8(this->diag_pos_max) ||
      !out->WriteU8(this->diag_neg_min) ||
      !out->WriteU8(this->diag_neg_max)) {
    return parent->Error("SubboxEntry: Failed to write");
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::
GlatEntry::ParsePart(Buffer& table) {
  if (!table.ReadS16(&this->attNum)) {
    return parent->Error("GlatEntry: Failed to read attNum");
  }
  if (!table.ReadS16(&this->num) || this->num < 0) {
    return parent->Error("GlatEntry: Failed to read valid num");
  }

  //this->attributes.resize(this->num);
  for (int i = 0; i < this->num; ++i) {
    this->attributes.emplace_back();
    if (!table.ReadS16(&this->attributes[i])) {
      return parent->Error("GlatEntry: Failed to read attribute %u", i);
    }
  }
  return true;
}

bool OpenTypeGLAT_v3::GlyphAttrs::
GlatEntry::SerializePart(OTSStream* out) const {
  if (!out->WriteS16(this->attNum) ||
      !out->WriteS16(this->num) ||
      !SerializeParts(this->attributes, out)) {
    return parent->Error("GlatEntry: Failed to write");
  }
  return true;
}

// -----------------------------------------------------------------------------
// OpenTypeGLAT
// -----------------------------------------------------------------------------

bool OpenTypeGLAT::Parse(const uint8_t* data, size_t length) {
  if (GetFont()->dropped_graphite) {
    return Drop("Skipping Graphite table");
  }
  Buffer table(data, length);
  uint32_t version;
  if (!table.ReadU32(&version)) {
    return DropGraphite("Failed to read version");
  }
  switch (version >> 16) {
    case 1:
      this->handler = new OpenTypeGLAT_v1(this->font, this->tag);
      break;
    case 2:
      this->handler = new OpenTypeGLAT_v2(this->font, this->tag);
      break;
    case 3: {
      this->handler = new OpenTypeGLAT_v3(this->font, this->tag);
      break;
    }
    default:
      return DropGraphite("Unsupported table version: %u", version >> 16);
  }
  return this->handler->Parse(data, length);
}

bool OpenTypeGLAT::Serialize(OTSStream* out) {
  if (!this->handler) {
    return Error("No Glat table parsed");
  }
  return this->handler->Serialize(out);
}

}  // namespace ots
