// Copyright (c) 2011-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 "name.h"

#include <algorithm>
#include <cstring>
#include <cctype>

// name - Naming Table
// http://www.microsoft.com/typography/otspec/name.htm

namespace {

// We disallow characters outside the URI spec "unreserved characters"
// set; any chars outside this set will be replaced by underscore.
bool AllowedInPsName(char c) {
  return isalnum(c) || std::strchr("-._~", c);
}

bool SanitizePsNameAscii(std::string& name) {
  if (name.size() > 63)
    return false;

  for (unsigned i = 0; i < name.size(); ++i) {
    if (!AllowedInPsName(name[i])) {
      name[i] = '_';
    }
  }
  return true;
}

bool SanitizePsNameUtf16Be(std::string& name) {
  if ((name.size() & 1) != 0)
    return false;
  if (name.size() > 2 * 63)
    return false;

  for (unsigned i = 0; i < name.size(); i += 2) {
    if (name[i] != 0) {
      // non-Latin1 char in psname? reject it altogether
      return false;
    }
    if (!AllowedInPsName(name[i+1])) {
      name[i] = '_';
    }
  }
  return true;
}

void AssignToUtf16BeFromAscii(std::string* target,
                              const std::string& source) {
  target->resize(source.size() * 2);
  for (unsigned i = 0, j = 0; i < source.size(); i++) {
    (*target)[j++] = '\0';
    (*target)[j++] = source[i];
  }
}

}  // namespace


namespace ots {

bool OpenTypeNAME::Parse(const uint8_t* data, size_t length) {
  Buffer table(data, length);

  uint16_t format = 0;
  if (!table.ReadU16(&format) || format > 1) {
    return Error("Failed to read table format or bad format %d", format);
  }

  uint16_t count = 0;
  if (!table.ReadU16(&count)) {
    return Error("Failed to read name count");
  }

  uint16_t string_offset = 0;
  if (!table.ReadU16(&string_offset) || string_offset > length) {
    return Error("Failed to read or bad stringOffset");
  }
  const char* string_base = reinterpret_cast<const char*>(data) +
      string_offset;

  bool sort_required = false;

  // Read all the names, discarding any with invalid IDs,
  // and any where the offset/length would be outside the table.
  // A stricter alternative would be to reject the font if there
  // are invalid name records, but it's not clear that is necessary.
  for (unsigned i = 0; i < count; ++i) {
    NameRecord rec;
    uint16_t name_length, name_offset = 0;
    if (!table.ReadU16(&rec.platform_id) ||
        !table.ReadU16(&rec.encoding_id) ||
        !table.ReadU16(&rec.language_id) ||
        !table.ReadU16(&rec.name_id) ||
        !table.ReadU16(&name_length) ||
        !table.ReadU16(&name_offset)) {
      return Error("Failed to read name entry %d", i);
    }
    // check platform & encoding, discard names with unknown values
    switch (rec.platform_id) {
      case 0:  // Unicode
        if (rec.encoding_id > 6) {
          continue;
        }
        break;
      case 1:  // Macintosh
        if (rec.encoding_id > 32) {
          continue;
        }
        break;
      case 2:  // ISO
        if (rec.encoding_id > 2) {
          continue;
        }
        break;
      case 3:  // Windows: IDs 7 to 9 are "reserved"
        if (rec.encoding_id > 6 && rec.encoding_id != 10) {
          continue;
        }
        break;
      case 4:  // Custom (OTF Windows NT compatibility)
        if (rec.encoding_id > 255) {
          continue;
        }
        break;
      default:  // unknown platform
        continue;
    }

    const unsigned name_end = static_cast<unsigned>(string_offset) +
        name_offset + name_length;
    if (name_end > length) {
      continue;
    }
    rec.text.resize(name_length);
    rec.text.assign(string_base + name_offset, name_length);

    if (rec.name_id == 6) {
      // PostScript name: "sanitize" it by replacing any chars outside the
      // URI spec "unreserved" set by underscore, or reject the name entirely
      // (and use a fallback) if it looks really broken.
      if (rec.platform_id == 1) {
        if (!SanitizePsNameAscii(rec.text)) {
          continue;
        }
      } else if (rec.platform_id == 0 || rec.platform_id == 3) {
        if (!SanitizePsNameUtf16Be(rec.text)) {
          continue;
        }
      }
    }

    if (!this->names.empty() && !(this->names.back() < rec)) {
      Warning("name records are not sorted.");
      sort_required = true;
    }

    this->names.push_back(rec);
    this->name_ids.insert(rec.name_id);
  }

  if (format == 1) {
    // extended name table format with language tags
    uint16_t lang_tag_count;
    if (!table.ReadU16(&lang_tag_count)) {
      return Error("Failed to read langTagCount");
    }
    for (unsigned i = 0; i < lang_tag_count; ++i) {
      uint16_t tag_length = 0;
      uint16_t tag_offset = 0;
      if (!table.ReadU16(&tag_length) || !table.ReadU16(&tag_offset)) {
        return Error("Faile to read length or offset for langTagRecord %d", i);
      }
      const unsigned tag_end = static_cast<unsigned>(string_offset) +
          tag_offset + tag_length;
      if (tag_end > length) {
        return Error("bad end of tag %d > %ld for langTagRecord %d", tag_end, length, i);
      }
      // Lang tag is BCP 47 tag per the spec, the recommonded BCP 47 max tag
      // length is 35:
      // https://tools.ietf.org/html/bcp47#section-4.4.1
      // We are being too generous and allowing for 100 (multiplied by 2 since
      // this is UTF-16 string).
      if (tag_length > 100 * 2) {
        return Error("Too long language tag for LangTagRecord %d: %d", i, tag_length);
      }
      std::string tag(string_base + tag_offset, tag_length);
      this->lang_tags.push_back(tag);
    }
  }

  if (table.offset() > string_offset) {
    // the string storage apparently overlapped the name/tag records;
    // consider this font to be badly broken
    return Error("Bad table offset %ld > %d", table.offset(), string_offset);
  }

  // check existence of required name strings (synthesize if necessary)
  //  [0 - copyright - skip]
  //   1 - family
  //   2 - subfamily
  //  [3 - unique ID - skip]
  //   4 - full name
  //   5 - version
  //   6 - postscript name
  static const uint16_t kStdNameCount = 7;
  static const char* kStdNames[kStdNameCount] = {
    NULL,
    "OTS derived font",
    "Unspecified",
    NULL,
    "OTS derived font",
    "1.000",
    "OTS-derived-font"
  };

  // scan the names to check whether the required "standard" ones are present;
  // if not, we'll add our fixed versions here
  bool mac_name[kStdNameCount] = { 0 };
  bool win_name[kStdNameCount] = { 0 };
  for (const auto& name : this->names) {
    const uint16_t id = name.name_id;
    if (id >= kStdNameCount || kStdNames[id] == NULL) {
      continue;
    }
    if (name.platform_id == 1) {
      mac_name[id] = true;
      continue;
    }
    if (name.platform_id == 3) {
      win_name[id] = true;
      continue;
    }
  }

  for (uint16_t i = 0; i < kStdNameCount; ++i) {
    if (kStdNames[i] == NULL) {
      continue;
    }
    if (!mac_name[i] && !win_name[i]) {
      NameRecord mac_rec(1 /* platform_id */, 0 /* encoding_id */,
                         0 /* language_id */ , i /* name_id */);
      mac_rec.text.assign(kStdNames[i]);

      NameRecord win_rec(3 /* platform_id */, 1 /* encoding_id */,
                         1033 /* language_id */ , i /* name_id */);
      AssignToUtf16BeFromAscii(&win_rec.text, std::string(kStdNames[i]));

      this->names.push_back(mac_rec);
      this->names.push_back(win_rec);
      sort_required = true;
    }
  }

  if (sort_required) {
    std::sort(this->names.begin(), this->names.end());
  }

  return true;
}

bool OpenTypeNAME::Serialize(OTSStream* out) {
  uint16_t name_count = static_cast<uint16_t>(this->names.size());
  uint16_t lang_tag_count = static_cast<uint16_t>(this->lang_tags.size());
  uint16_t format = 0;
  size_t string_offset = 6 + name_count * 12;

  if (this->lang_tags.size() > 0) {
    // lang tags require a format-1 name table
    format = 1;
    string_offset += 2 + lang_tag_count * 4;
  }
  if (string_offset > 0xffff) {
    return Error("Bad stringOffset: %ld", string_offset);
  }
  if (!out->WriteU16(format) ||
      !out->WriteU16(name_count) ||
      !out->WriteU16(static_cast<uint16_t>(string_offset))) {
    return Error("Failed to write name header");
  }

  std::string string_data;
  for (const auto& rec : this->names) {
    if (string_data.size() + rec.text.size() >
            std::numeric_limits<uint16_t>::max() ||
        !out->WriteU16(rec.platform_id) ||
        !out->WriteU16(rec.encoding_id) ||
        !out->WriteU16(rec.language_id) ||
        !out->WriteU16(rec.name_id) ||
        !out->WriteU16(static_cast<uint16_t>(rec.text.size())) ||
        !out->WriteU16(static_cast<uint16_t>(string_data.size())) ) {
      return Error("Faile to write nameRecord");
    }
    string_data.append(rec.text);
  }

  if (format == 1) {
    if (!out->WriteU16(lang_tag_count)) {
      return Error("Faile to write langTagCount");
    }
    for (const auto& tag : this->lang_tags) {
      if (string_data.size() + tag.size() >
              std::numeric_limits<uint16_t>::max() ||
          !out->WriteU16(static_cast<uint16_t>(tag.size())) ||
          !out->WriteU16(static_cast<uint16_t>(string_data.size()))) {
        return Error("Failed to write langTagRecord");
      }
      string_data.append(tag);
    }
  }

  if (!out->Write(string_data.data(), string_data.size())) {
    return Error("Faile to write string data");
  }

  return true;
}

bool OpenTypeNAME::IsValidNameId(uint16_t nameID, bool addIfMissing) {
  if (addIfMissing && !this->name_ids.count(nameID)) {
    bool added_unicode = false;
    bool added_macintosh = false;
    bool added_windows = false;
    const size_t names_size = this->names.size();  // original size
    for (size_t i = 0; i < names_size; ++i) switch (names[i].platform_id) {
     case 0:
      if (!added_unicode) {
        // If there is an existing NameRecord with platform_id == 0 (Unicode),
        // then add a NameRecord for the the specified nameID with arguments
        // 0 (Unicode), 0 (v1.0), 0 (unspecified language).
        this->names.emplace_back(0, 0, 0, nameID);
        this->names.back().text = "NoName";
        added_unicode = true;
      }
      break;
     case 1:
      if (!added_macintosh) {
        // If there is an existing NameRecord with platform_id == 1 (Macintosh),
        // then add a NameRecord for the specified nameID with arguments
        // 1 (Macintosh), 0 (Roman), 0 (English).
        this->names.emplace_back(1, 0, 0, nameID);
        this->names.back().text = "NoName";
        added_macintosh = true;
      }
      break;
     case 3:
      if (!added_windows) {
        // If there is an existing NameRecord with platform_id == 3 (Windows),
        // then add a NameRecord for the specified nameID with arguments
        // 3 (Windows), 1 (UCS), 1033 (US English).
        this->names.emplace_back(3, 1, 1033, nameID);
        this->names.back().text = "NoName";
        added_windows = true;
      }
      break;
    }
    if (added_unicode || added_macintosh || added_windows) {
      std::sort(this->names.begin(), this->names.end());
      this->name_ids.insert(nameID);
    }
  }
  return this->name_ids.count(nameID);
}

}  // namespace
