/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * 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.
 */

// Determine coverage of font given its raw "cmap" OpenType table

#include "minikin/CmapCoverage.h"

#include <algorithm>
#include <vector>

#include "minikin/Range.h"
#include "minikin/SparseBitSet.h"

#include "MinikinInternal.h"

namespace minikin {

// These could perhaps be optimized to use __builtin_bswap16 and friends.
static uint32_t readU16(const uint8_t* data, size_t offset) {
    return ((uint32_t)data[offset]) << 8 | ((uint32_t)data[offset + 1]);
}

static uint32_t readU24(const uint8_t* data, size_t offset) {
    return ((uint32_t)data[offset]) << 16 | ((uint32_t)data[offset + 1]) << 8 |
           ((uint32_t)data[offset + 2]);
}

static uint32_t readU32(const uint8_t* data, size_t offset) {
    return ((uint32_t)data[offset]) << 24 | ((uint32_t)data[offset + 1]) << 16 |
           ((uint32_t)data[offset + 2]) << 8 | ((uint32_t)data[offset + 3]);
}

// The start must be larger than or equal to coverage.back() if coverage is not empty.
// Returns true if the range is appended. Otherwise returns false as an error.
static bool addRange(std::vector<uint32_t>& coverage, uint32_t start, uint32_t end) {
    if (coverage.empty() || coverage.back() < start) {
        coverage.push_back(start);
        coverage.push_back(end);
        return true;
    } else if (coverage.back() == start) {
        coverage.back() = end;
        return true;
    } else {
        // Reject unordered range input since SparseBitSet assumes that the given range vector is
        // sorted. OpenType specification says cmap entries are sorted in order of code point
        // values, thus for OpenType compliant font files, we don't reach here.
        android_errorWriteLog(0x534e4554, "32178311");
        return false;
    }
}

// Returns true if the range is appended. Otherwise returns false as an error.
static bool addRangeCmap4(std::vector<uint32_t>& coverage, uint32_t start, uint32_t end) {
    if (!coverage.empty() && coverage.back() > end) {
        // Reject unordered end code points.
        return false;
    }
    if (coverage.empty() || coverage.back() < start) {
        coverage.push_back(start);
        coverage.push_back(end);
        return true;
    } else {
        coverage.back() = end;
        return true;
    }
}

// Returns Range from given ranges vector. Returns invalidRange if i is out of range.
static inline Range getRange(const std::vector<uint32_t>& r, size_t i) {
    return i + 1 < r.size() ? Range({r[i], r[i + 1]}) : Range::invalidRange();
}

// Merge two sorted lists of ranges into one sorted list.
static std::vector<uint32_t> mergeRanges(const std::vector<uint32_t>& lRanges,
                                         const std::vector<uint32_t>& rRanges) {
    std::vector<uint32_t> out;

    const size_t lsize = lRanges.size();
    const size_t rsize = rRanges.size();
    out.reserve(lsize + rsize);
    size_t ri = 0;
    size_t li = 0;
    while (li < lsize || ri < rsize) {
        Range left = getRange(lRanges, li);
        Range right = getRange(rRanges, ri);

        if (!right.isValid()) {
            // No ranges left in rRanges. Just put all remaining ranges in lRanges.
            do {
                Range r = getRange(lRanges, li);
                addRange(out, r.getStart(), r.getEnd());  // Input is sorted. Never returns false.
                li += 2;
            } while (li < lsize);
            break;
        } else if (!left.isValid()) {
            // No ranges left in lRanges. Just put all remaining ranges in rRanges.
            do {
                Range r = getRange(rRanges, ri);
                addRange(out, r.getStart(), r.getEnd());  // Input is sorted. Never returns false.
                ri += 2;
            } while (ri < rsize);
            break;
        } else if (!Range::intersects(left, right)) {
            // No intersection. Add smaller range.
            if (left.getStart() < right.getStart()) {
                // Input is sorted. Never returns false.
                addRange(out, left.getStart(), left.getEnd());
                li += 2;
            } else {
                // Input is sorted. Never returns false.
                addRange(out, right.getStart(), right.getEnd());
                ri += 2;
            }
        } else {
            Range merged = Range::merge(left, right);
            li += 2;
            ri += 2;
            left = getRange(lRanges, li);
            right = getRange(rRanges, ri);
            while (Range::intersects(merged, left) || Range::intersects(merged, right)) {
                if (Range::intersects(merged, left)) {
                    merged = Range::merge(merged, left);
                    li += 2;
                    left = getRange(lRanges, li);
                } else {
                    merged = Range::merge(merged, right);
                    ri += 2;
                    right = getRange(rRanges, ri);
                }
            }
            // Input is sorted. Never returns false.
            addRange(out, merged.getStart(), merged.getEnd());
        }
    }

    return out;
}

// Get the coverage information out of a Format 4 subtable, storing it in the coverage vector
static bool getCoverageFormat4(std::vector<uint32_t>& coverage, const uint8_t* data, size_t size) {
    const size_t kSegCountOffset = 6;
    const size_t kEndCountOffset = 14;
    const size_t kHeaderSize = 16;
    const size_t kSegmentSize = 8;  // total size of array elements for one segment
    if (kEndCountOffset > size) {
        return false;
    }
    size_t segCount = readU16(data, kSegCountOffset) >> 1;
    if (kHeaderSize + segCount * kSegmentSize > size) {
        return false;
    }
    for (size_t i = 0; i < segCount; i++) {
        uint32_t end = readU16(data, kEndCountOffset + 2 * i);
        uint32_t start = readU16(data, kHeaderSize + 2 * (segCount + i));
        if (end < start) {
            // invalid segment range: size must be positive
            android_errorWriteLog(0x534e4554, "26413177");
            return false;
        }
        uint32_t rangeOffset = readU16(data, kHeaderSize + 2 * (3 * segCount + i));
        if (rangeOffset == 0) {
            uint32_t delta = readU16(data, kHeaderSize + 2 * (2 * segCount + i));
            if (((end + delta) & 0xffff) > end - start) {
                if (!addRangeCmap4(coverage, start, end + 1)) {
                    return false;
                }
            } else {
                for (uint32_t j = start; j < end + 1; j++) {
                    if (((j + delta) & 0xffff) != 0) {
                        if (!addRangeCmap4(coverage, j, j + 1)) {
                            return false;
                        }
                    }
                }
            }
        } else {
            for (uint32_t j = start; j < end + 1; j++) {
                uint32_t actualRangeOffset =
                        kHeaderSize + 6 * segCount + rangeOffset + (i + j - start) * 2;
                if (actualRangeOffset + 2 > size) {
                    // invalid rangeOffset is considered a "warning" by OpenType Sanitizer
                    continue;
                }
                uint32_t glyphId = readU16(data, actualRangeOffset);
                if (glyphId != 0) {
                    if (!addRangeCmap4(coverage, j, j + 1)) {
                        return false;
                    }
                }
            }
        }
    }
    return true;
}

// Get the coverage information out of a Format 12 subtable, storing it in the coverage vector
static bool getCoverageFormat12(std::vector<uint32_t>& coverage, const uint8_t* data, size_t size) {
    const size_t kNGroupsOffset = 12;
    const size_t kFirstGroupOffset = 16;
    const size_t kGroupSize = 12;
    const size_t kStartCharCodeOffset = 0;
    const size_t kEndCharCodeOffset = 4;
    const size_t kMaxNGroups = 0xfffffff0 / kGroupSize;  // protection against overflow
    // For all values < kMaxNGroups, kFirstGroupOffset + nGroups * kGroupSize fits in 32 bits.
    if (kFirstGroupOffset > size) {
        return false;
    }
    uint32_t nGroups = readU32(data, kNGroupsOffset);
    if (nGroups >= kMaxNGroups || kFirstGroupOffset + nGroups * kGroupSize > size) {
        android_errorWriteLog(0x534e4554, "25645298");
        return false;
    }
    for (uint32_t i = 0; i < nGroups; i++) {
        uint32_t groupOffset = kFirstGroupOffset + i * kGroupSize;
        uint32_t start = readU32(data, groupOffset + kStartCharCodeOffset);
        uint32_t end = readU32(data, groupOffset + kEndCharCodeOffset);
        if (end < start) {
            // invalid group range: size must be positive
            android_errorWriteLog(0x534e4554, "26413177");
            return false;
        }

        // No need to read outside of Unicode code point range.
        if (start > MAX_UNICODE_CODE_POINT) {
            return true;
        }
        if (end > MAX_UNICODE_CODE_POINT) {
            // file is inclusive, vector is exclusive
            if (end == 0xFFFFFFFF) {
                android_errorWriteLog(0x534e4554, "62134807");
            }
            return addRange(coverage, start, MAX_UNICODE_CODE_POINT + 1);
        }
        if (!addRange(coverage, start, end + 1)) {  // file is inclusive, vector is exclusive
            return false;
        }
    }
    return true;
}

// Lower value has higher priority. 0 for the highest priority table.
// kLowestPriority for unsupported tables.
// This order comes from HarfBuzz's hb-ot-font.cc and needs to be kept in sync with it.
constexpr uint8_t kLowestPriority = 255;
uint8_t getTablePriority(uint16_t platformId, uint16_t encodingId) {
    if (platformId == 3 && encodingId == 10) {
        return 0;
    }
    if (platformId == 0 && encodingId == 6) {
        return 1;
    }
    if (platformId == 0 && encodingId == 4) {
        return 2;
    }
    if (platformId == 3 && encodingId == 1) {
        return 3;
    }
    if (platformId == 0 && encodingId == 3) {
        return 4;
    }
    if (platformId == 0 && encodingId == 2) {
        return 5;
    }
    if (platformId == 0 && encodingId == 1) {
        return 6;
    }
    if (platformId == 0 && encodingId == 0) {
        return 7;
    }
    // Tables other than above are not supported.
    return kLowestPriority;
}

// Get merged coverage information from default UVS Table and non-default UVS Table. Note that this
// function assumes code points in both default UVS Table and non-default UVS table are stored in
// ascending order. This is required by the standard.
static bool getVSCoverage(std::vector<uint32_t>* out_ranges, const uint8_t* data, size_t size,
                          uint32_t defaultUVSTableOffset, uint32_t nonDefaultUVSTableOffset,
                          const SparseBitSet& baseCoverage) {
    // Need to merge supported ranges from default UVS Table and non-default UVS Table.
    // First, collect all supported code points from non default UVS table.
    std::vector<uint32_t> rangesFromNonDefaultUVSTable;
    if (nonDefaultUVSTableOffset != 0) {
        constexpr size_t kHeaderSize = 4;
        constexpr size_t kUVSMappingRecordSize = 5;

        const uint8_t* nonDefaultUVSTable = data + nonDefaultUVSTableOffset;
        // This subtraction doesn't underflow since the caller already checked
        // size > nonDefaultUVSTableOffset.
        const size_t nonDefaultUVSTableRemaining = size - nonDefaultUVSTableOffset;
        if (nonDefaultUVSTableRemaining < kHeaderSize) {
            return false;
        }
        const uint64_t numRecords = readU32(nonDefaultUVSTable, 0);
        const uint64_t sizeToRead = numRecords * kUVSMappingRecordSize + kHeaderSize;
        if (sizeToRead > nonDefaultUVSTableRemaining) {
            if (sizeToRead > UINT_MAX) {
                android_errorWriteLog(0x534e4554, "70808908");
            }
            return false;
        }
        for (uint32_t i = 0; i < numRecords; ++i) {
            const size_t recordOffset = kHeaderSize + kUVSMappingRecordSize * i;
            const uint32_t codePoint = readU24(nonDefaultUVSTable, recordOffset);
            if (!addRange(rangesFromNonDefaultUVSTable, codePoint, codePoint + 1)) {
                return false;
            }
        }
    }

    // Then, construct range from default UVS Table with merging code points from non default UVS
    // table.
    std::vector<uint32_t> rangesFromDefaultUVSTable;
    if (defaultUVSTableOffset != 0) {
        constexpr size_t kHeaderSize = 4;
        constexpr size_t kUnicodeRangeRecordSize = 4;

        const uint8_t* defaultUVSTable = data + defaultUVSTableOffset;
        // This subtraction doesn't underflow since the caller already checked
        // size > defaultUVSTableOffset.
        const size_t defaultUVSTableRemaining = size - defaultUVSTableOffset;

        if (defaultUVSTableRemaining < kHeaderSize) {
            return false;
        }
        const uint64_t numRecords = readU32(defaultUVSTable, 0);
        const uint64_t sizeToRead = numRecords * kUnicodeRangeRecordSize + kHeaderSize;
        if (sizeToRead > defaultUVSTableRemaining) {
            if (sizeToRead > UINT_MAX) {
                android_errorWriteLog(0x534e4554, "70808908");
            }
            return false;
        }

        for (uint32_t i = 0; i < numRecords; ++i) {
            const size_t recordOffset = kHeaderSize + kUnicodeRangeRecordSize * i;
            const uint32_t startCp = readU24(defaultUVSTable, recordOffset);
            const uint8_t rangeLength = defaultUVSTable[recordOffset + 3];

            // Then insert range from default UVS Table, but exclude if the base codepoint is not
            // supported.
            for (uint32_t cp = startCp; cp <= startCp + rangeLength; ++cp) {
                // All codepoints in default UVS table should go to the glyphs of the codepoints
                // without variation selectors. We need to check the default glyph availability and
                // exclude the codepoint if it is not supported by defualt cmap table.
                if (baseCoverage.get(cp)) {
                    if (!addRange(rangesFromDefaultUVSTable, cp, cp + 1 /* exclusive */)) {
                        return false;
                    }
                }
            }
        }
    }
    *out_ranges = mergeRanges(rangesFromDefaultUVSTable, rangesFromNonDefaultUVSTable);
    return true;
}

static void getCoverageFormat14(std::vector<std::unique_ptr<SparseBitSet>>* out,
                                const uint8_t* data, size_t size,
                                const SparseBitSet& baseCoverage) {
    constexpr size_t kHeaderSize = 10;
    constexpr size_t kRecordSize = 11;
    constexpr size_t kLengthOffset = 2;
    constexpr size_t kNumRecordOffset = 6;

    out->clear();
    if (size < kHeaderSize) {
        return;
    }

    const uint32_t length = readU32(data, kLengthOffset);
    if (size < length) {
        return;
    }

    const uint64_t numRecords = readU32(data, kNumRecordOffset);
    const uint64_t sizeToRead = kHeaderSize + kRecordSize * numRecords;
    if (numRecords == 0 || sizeToRead > length) {
        if (sizeToRead > UINT_MAX) {
            android_errorWriteLog(0x534e4554, "70808908");
        }
        return;
    }

    for (uint32_t i = 0; i < numRecords; ++i) {
        // Insert from the largest code points since it determines the size of the output vector.
        const uint32_t recordHeadOffset = kHeaderSize + kRecordSize * (numRecords - i - 1);
        const uint32_t vsCodePoint = readU24(data, recordHeadOffset);
        const uint32_t defaultUVSOffset = readU32(data, recordHeadOffset + 3);
        const uint32_t nonDefaultUVSOffset = readU32(data, recordHeadOffset + 7);
        if (defaultUVSOffset > length || nonDefaultUVSOffset > length) {
            continue;
        }

        const uint16_t vsIndex = getVsIndex(vsCodePoint);
        if (vsIndex == INVALID_VS_INDEX) {
            continue;
        }
        std::vector<uint32_t> ranges;
        if (!getVSCoverage(&ranges, data, length, defaultUVSOffset, nonDefaultUVSOffset,
                           baseCoverage)) {
            continue;
        }
        if (out->size() < vsIndex + 1) {
            out->resize(vsIndex + 1);
        }
        (*out)[vsIndex].reset(new SparseBitSet(ranges.data(), ranges.size() >> 1));
    }

    out->shrink_to_fit();
}

SparseBitSet CmapCoverage::getCoverage(const uint8_t* cmap_data, size_t cmap_size,
                                       std::vector<std::unique_ptr<SparseBitSet>>* out) {
    constexpr size_t kHeaderSize = 4;
    constexpr size_t kNumTablesOffset = 2;
    constexpr size_t kTableSize = 8;
    constexpr size_t kPlatformIdOffset = 0;
    constexpr size_t kEncodingIdOffset = 2;
    constexpr size_t kOffsetOffset = 4;
    constexpr size_t kFormatOffset = 0;
    constexpr uint32_t kNoTable = UINT32_MAX;

    if (kHeaderSize > cmap_size) {
        return SparseBitSet();
    }
    uint32_t numTables = readU16(cmap_data, kNumTablesOffset);
    if (kHeaderSize + numTables * kTableSize > cmap_size) {
        return SparseBitSet();
    }

    uint32_t bestTableOffset = kNoTable;
    uint16_t bestTableFormat = 0;
    uint8_t bestTablePriority = kLowestPriority;
    uint32_t vsTableOffset = kNoTable;
    for (uint32_t i = 0; i < numTables; ++i) {
        const uint32_t tableHeadOffset = kHeaderSize + i * kTableSize;
        const uint16_t platformId = readU16(cmap_data, tableHeadOffset + kPlatformIdOffset);
        const uint16_t encodingId = readU16(cmap_data, tableHeadOffset + kEncodingIdOffset);
        const uint32_t offset = readU32(cmap_data, tableHeadOffset + kOffsetOffset);

        if (offset > cmap_size - 2) {
            continue;  // Invalid table: not enough space to read.
        }
        const uint16_t format = readU16(cmap_data, offset + kFormatOffset);

        if (platformId == 0 /* Unicode */ && encodingId == 5 /* Variation Sequences */) {
            if (vsTableOffset == kNoTable && format == 14) {
                vsTableOffset = offset;
            } else {
                // Ignore the (0, 5) table if we have already seen another valid one or it's in a
                // format we don't understand.
            }
        } else {
            uint32_t length;
            uint32_t language;

            if (format == 4) {
                constexpr size_t lengthOffset = 2;
                constexpr size_t languageOffset = 4;
                constexpr size_t minTableSize = languageOffset + 2;
                if (offset > cmap_size - minTableSize) {
                    continue;  // Invalid table: not enough space to read.
                }
                length = readU16(cmap_data, offset + lengthOffset);
                language = readU16(cmap_data, offset + languageOffset);
            } else if (format == 12) {
                constexpr size_t lengthOffset = 4;
                constexpr size_t languageOffset = 8;
                constexpr size_t minTableSize = languageOffset + 4;
                if (offset > cmap_size - minTableSize) {
                    continue;  // Invalid table: not enough space to read.
                }
                length = readU32(cmap_data, offset + lengthOffset);
                language = readU32(cmap_data, offset + languageOffset);
            } else {
                continue;
            }

            if (length > cmap_size - offset) {
                continue;  // Invalid table: table length is larger than whole cmap data size.
            }
            if (language != 0) {
                // Unsupported or invalid table: this is either a subtable for the Macintosh
                // platform (which we don't support), or an invalid subtable since language field
                // should be zero for non-Macintosh subtables.
                continue;
            }
            const uint8_t priority = getTablePriority(platformId, encodingId);
            if (priority < bestTablePriority) {
                bestTableOffset = offset;
                bestTablePriority = priority;
                bestTableFormat = format;
            }
        }
        if (vsTableOffset != kNoTable && bestTablePriority == 0 /* highest priority */) {
            // Already found the highest priority table and variation sequences table. No need to
            // look at remaining tables.
            break;
        }
    }

    SparseBitSet coverage;

    if (bestTableOffset != kNoTable) {
        const uint8_t* tableData = cmap_data + bestTableOffset;
        const size_t tableSize = cmap_size - bestTableOffset;
        bool success;
        std::vector<uint32_t> coverageVec;
        if (bestTableFormat == 4) {
            success = getCoverageFormat4(coverageVec, tableData, tableSize);
        } else {
            success = getCoverageFormat12(coverageVec, tableData, tableSize);
        }

        if (success) {
            coverage = SparseBitSet(&coverageVec.front(), coverageVec.size() >> 1);
        }
    }

    if (vsTableOffset != kNoTable) {
        const uint8_t* tableData = cmap_data + vsTableOffset;
        const size_t tableSize = cmap_size - vsTableOffset;
        getCoverageFormat14(out, tableData, tableSize, coverage);
    }
    return coverage;
}

}  // namespace minikin
