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

#if defined(STARBOARD)
#include "starboard/client_porting/poem/string_poem.h"
#define STRCHR_OTS strchr
#else
#define STRCHR_OTS std::strchr
#endif

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

namespace {

bool ValidInPsName(char c) {
  return (c > 0x20 && c < 0x7f && !STRCHR_OTS("[](){}<>/%", c));
}

bool CheckPsNameAscii(const std::string& name) {
  for (unsigned i = 0; i < name.size(); ++i) {
    if (!ValidInPsName(name[i])) {
      return false;
    }
  }
  return true;
}

bool CheckPsNameUtf16Be(const std::string& name) {
  if ((name.size() & 1) != 0)
    return false;

  for (unsigned i = 0; i < name.size(); i += 2) {
    if (name[i] != 0) {
      return false;
    }
    if (!ValidInPsName(name[i+1])) {
      return false;
    }
  }
  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: check that it is valid, if not then discard it
      if (rec.platform_id == 1) {
        if (!CheckPsNameAscii(rec.text)) {
          continue;
        }
      } else if (rec.platform_id == 0 || rec.platform_id == 3) {
        if (!CheckPsNameUtf16Be(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);
      }
      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 (std::vector<NameRecord>::iterator name_iter = this->names.begin();
       name_iter != this->names.end(); ++name_iter) {
    const uint16_t id = name_iter->name_id;
    if (id >= kStdNameCount || kStdNames[id] == NULL) {
      continue;
    }
    if (name_iter->platform_id == 1) {
      mac_name[id] = true;
      continue;
    }
    if (name_iter->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 (std::vector<NameRecord>::const_iterator name_iter = this->names.begin();
       name_iter != this->names.end(); ++name_iter) {
    const NameRecord& rec = *name_iter;
    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 (std::vector<std::string>::const_iterator tag_iter =
             this->lang_tags.begin();
         tag_iter != this->lang_tags.end(); ++tag_iter) {
      if (string_data.size() + tag_iter->size() >
              std::numeric_limits<uint16_t>::max() ||
          !out->WriteU16(static_cast<uint16_t>(tag_iter->size())) ||
          !out->WriteU16(static_cast<uint16_t>(string_data.size()))) {
        return Error("Failed to write langTagRecord");
      }
      string_data.append(*tag_iter);
    }
  }

  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

#undef STRCHR_OTS
