/*
 * Copyright (C) 2016 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "CSSFontFaceSet.h"

#include "CSSFontFaceSource.h"
#include "CSSFontFamily.h"
#include "CSSFontSelector.h"
#include "CSSFontStyleValue.h"
#include "CSSParser.h"
#include "CSSPrimitiveValue.h"
#include "CSSPropertyParserHelpers.h"
#include "CSSPropertyParserWorkerSafe.h"
#include "CSSSegmentedFontFace.h"
#include "CSSValueList.h"
#include "CSSValuePool.h"
#include "FontCache.h"
#include "StyleBuilderConverter.h"
#include "StyleProperties.h"

namespace WebCore {

CSSFontFaceSet::CSSFontFaceSet(CSSFontSelector* owningFontSelector)
    : m_owningFontSelector(owningFontSelector)
{
}

CSSFontFaceSet::~CSSFontFaceSet()
{
    for (auto& face : m_faces)
        face->removeClient(*this);

    for (auto& pair : m_locallyInstalledFacesLookupTable) {
        for (auto& face : pair.value)
            face->removeClient(*this);
    }
}

void CSSFontFaceSet::addFontModifiedObserver(const FontModifiedObserver& fontModifiedObserver)
{
    auto result = m_fontModifiedObservers.add(fontModifiedObserver);
    ASSERT_UNUSED(result, result.isNewEntry);
}

void CSSFontFaceSet::addFontEventClient(const FontEventClient& fontEventClient)
{
    auto result = m_fontEventClients.add(fontEventClient);
    ASSERT_UNUSED(result, result.isNewEntry);
}

void CSSFontFaceSet::incrementActiveCount()
{
    ++m_activeCount;
    if (m_activeCount == 1) {
        m_status = Status::Loading;
        m_fontEventClients.forEach([] (auto& client) {
            client.startedLoading();
        });
    }
}

void CSSFontFaceSet::decrementActiveCount()
{
    --m_activeCount;
    if (!m_activeCount) {
        m_status = Status::Loaded;
        m_fontEventClients.forEach([] (auto& client) {
            client.completedLoading();
        });
    }
}

bool CSSFontFaceSet::hasFace(const CSSFontFace& face) const
{
    for (auto& myFace : m_faces) {
        if (myFace.ptr() == &face)
            return true;
    }

    return false;
}

// Calling updateStyleIfNeeded() might delete |this|.
void CSSFontFaceSet::updateStyleIfNeeded()
{
    if (m_owningFontSelector)
        m_owningFontSelector->updateStyleIfNeeded();
}

void CSSFontFaceSet::ensureLocalFontFacesForFamilyRegistered(const String& familyName)
{
    ASSERT(m_owningFontSelector);
    if (m_locallyInstalledFacesLookupTable.contains(familyName))
        return;

    if (!m_owningFontSelector->scriptExecutionContext())
        return;
    AllowUserInstalledFonts allowUserInstalledFonts = m_owningFontSelector->scriptExecutionContext()->settingsValues().shouldAllowUserInstalledFonts ? AllowUserInstalledFonts::Yes : AllowUserInstalledFonts::No;
    Vector<FontSelectionCapabilities> capabilities = m_owningFontSelector->scriptExecutionContext()->fontCache().getFontSelectionCapabilitiesInFamily(familyName, allowUserInstalledFonts);
    if (capabilities.isEmpty())
        return;

    Vector<Ref<CSSFontFace>> faces;
    for (auto item : capabilities) {
        auto face = CSSFontFace::create(*m_owningFontSelector, nullptr, nullptr, true);
        
        Ref<CSSValueList> familyList = CSSValueList::createCommaSeparated();
        familyList->append(m_owningFontSelector->scriptExecutionContext()->cssValuePool().createFontFamilyValue(familyName));
        face->setFamilies(familyList.get());
        face->setFontSelectionCapabilities(item);
        face->adoptSource(makeUnique<CSSFontFaceSource>(face.get(), familyName));
        ASSERT(!face->computeFailureState());
        faces.append(WTFMove(face));
    }
    m_locallyInstalledFacesLookupTable.add(familyName, WTFMove(faces));
}

String CSSFontFaceSet::familyNameFromPrimitive(const CSSPrimitiveValue& value)
{
    if (value.isFontFamily())
        return value.fontFamily().familyName;
    if (!value.isValueID())
        return { };

    // We need to use the raw text for all the generic family types, since @font-face is a way of actually
    // defining what font to use for those types.
    switch (value.valueID()) {
    case CSSValueSerif:
        return serifFamily.get();
    case CSSValueSansSerif:
        return sansSerifFamily.get();
    case CSSValueCursive:
        return cursiveFamily.get();
    case CSSValueFantasy:
        return fantasyFamily.get();
    case CSSValueMonospace:
        return monospaceFamily.get();
    case CSSValueWebkitPictograph:
        return pictographFamily.get();
    case CSSValueSystemUi:
        return systemUiFamily.get();
    default:
        return { };
    }
}

void CSSFontFaceSet::addToFacesLookupTable(CSSFontFace& face)
{
    if (!face.families()) {
        // If the font has failed, there's no point in actually adding it to m_facesLookupTable,
        // because no font requests can actually use it for anything. So, let's just ... not add it.
        return;
    }
    auto families = face.families().value();

    for (auto& item : *families) {
        String familyName = CSSFontFaceSet::familyNameFromPrimitive(downcast<CSSPrimitiveValue>(item.get()));
        if (familyName.isEmpty())
            continue;

        auto addResult = m_facesLookupTable.add(familyName, Vector<Ref<CSSFontFace>>());
        auto& familyFontFaces = addResult.iterator->value;
        if (addResult.isNewEntry) {
            // m_locallyInstalledFontFaces grows without bound, eventually encorporating every font installed on the system.
            // This is by design.
            if (m_owningFontSelector)
                ensureLocalFontFacesForFamilyRegistered(familyName);
            familyFontFaces = { };
        }

        familyFontFaces.append(face);
    }
}

void CSSFontFaceSet::add(CSSFontFace& face)
{
    ASSERT(!hasFace(face));

    m_fontModifiedObservers.forEach([] (auto& observer) {
        observer();
    });

    face.addClient(*this);
    m_cache.clear();

    if (face.cssConnection())
        m_faces.insert(m_facesPartitionIndex++, face);
    else
        m_faces.append(face);

    addToFacesLookupTable(face);

    if (face.status() == CSSFontFace::Status::Loading || face.status() == CSSFontFace::Status::TimedOut)
        incrementActiveCount();

    if (face.cssConnection()) {
        ASSERT(!m_constituentCSSConnections.contains(face.cssConnection()));
        m_constituentCSSConnections.add(face.cssConnection(), &face);
    }
}

void CSSFontFaceSet::removeFromFacesLookupTable(const CSSFontFace& face, const CSSValueList& familiesToSearchFor)
{
    for (auto& item : familiesToSearchFor) {
        String familyName = CSSFontFaceSet::familyNameFromPrimitive(downcast<CSSPrimitiveValue>(item.get()));
        if (familyName.isEmpty())
            continue;

        auto iterator = m_facesLookupTable.find(familyName);
        if (iterator == m_facesLookupTable.end()) {
            // The font may have failed even before addToFacesLookupTable() was called on it,
            // which means we never added it (because there's no point in adding a failed font).
            // So, if it was never added, removing it is free! Woohoo!
            return;
        }
        bool found = false;
        for (size_t i = 0; i < iterator->value.size(); ++i) {
            if (iterator->value[i].ptr() == &face) {
                found = true;
                iterator->value.remove(i);
                break;
            }
        }
        ASSERT_UNUSED(found, found);
        if (!iterator->value.size())
            m_facesLookupTable.remove(iterator);
    }
}

void CSSFontFaceSet::remove(const CSSFontFace& face)
{
    Ref protect { face };

    m_cache.clear();

    m_fontModifiedObservers.forEach([] (auto& observer) {
        observer();
    });
    
    if (face.families())
        removeFromFacesLookupTable(face, *face.families().value());

    if (face.cssConnection()) {
        ASSERT(m_constituentCSSConnections.get(face.cssConnection()) == &face);
        m_constituentCSSConnections.remove(face.cssConnection());
    }

    for (size_t i = 0; i < m_faces.size(); ++i) {
        if (m_faces[i].ptr() == &face) {
            if (i < m_facesPartitionIndex)
                --m_facesPartitionIndex;
            m_faces[i]->removeClient(*this);
            m_faces.remove(i);
            if (face.status() == CSSFontFace::Status::Loading || face.status() == CSSFontFace::Status::TimedOut)
                decrementActiveCount();
            return;
        }
    }
    ASSERT_NOT_REACHED();
}

CSSFontFace* CSSFontFaceSet::lookUpByCSSConnection(StyleRuleFontFace& target)
{
    return m_constituentCSSConnections.get(&target);
}

void CSSFontFaceSet::purge()
{
    Vector<Ref<CSSFontFace>> toRemove;
    for (auto& face : m_faces) {
        if (face->purgeable())
            toRemove.append(face.copyRef());
    }

    for (auto& item : toRemove)
        remove(item.get());
}

void CSSFontFaceSet::emptyCaches()
{
    m_cache.clear();
}

void CSSFontFaceSet::clear()
{
    for (auto& face : m_faces)
        face->removeClient(*this);
    m_faces.clear();
    m_facesLookupTable.clear();
    m_locallyInstalledFacesLookupTable.clear();
    m_cache.clear();
    m_constituentCSSConnections.clear();
    m_facesPartitionIndex = 0;
    m_status = Status::Loaded;
}

CSSFontFace& CSSFontFaceSet::operator[](size_t i)
{
    ASSERT(i < faceCount());
    return m_faces[i];
}

static FontSelectionRequest computeFontSelectionRequest(CSSPropertyParserHelpers::FontRaw& font)
{
    auto weightSelectionValue = font.weight
        ? WTF::switchOn(*font.weight, [&] (CSSValueID keyword) {
            switch (keyword) {
            case CSSValueNormal:
                return normalWeightValue();
            case CSSValueBold:
            case CSSValueBolder:
                return boldWeightValue();
            case CSSValueLighter:
                return lightWeightValue();
            default:
                ASSERT_NOT_REACHED();
                return normalWeightValue();
            }
        }, [&] (double weight) {
            return FontSelectionValue::clampFloat(weight);
        }) : normalWeightValue();

    // Because this is a FontRaw, we know we should be able to dereference stretchSelectionValue as
    // consumeFontStretchKeywordValueRaw only returns results valid to pass to fontStretchValue.
    auto stretchSelectionValue = fontStretchValue(font.stretch.value_or(CSSValueNormal));
    ASSERT(stretchSelectionValue);

    auto styleKeyword = font.style ? font.style->style : CSSValueNormal;
    auto styleSelectionValue = [&] () -> std::optional<FontSelectionValue> {
        if (styleKeyword == CSSValueNormal)
            return std::nullopt;
        if (styleKeyword == CSSValueItalic)
            return italicValue();
        ASSERT(font.style && styleKeyword == CSSValueOblique);
        float degrees = 0;
        if (font.style->angle)
            degrees = static_cast<float>(CSSPrimitiveValue::computeDegrees(font.style->angle->type, font.style->angle->value));
        return FontSelectionValue(degrees);
    }();

    return { weightSelectionValue, *stretchSelectionValue, styleSelectionValue };
}

using CodePointsMap = HashSet<UChar32, DefaultHash<UChar32>, WTF::UnsignedWithZeroKeyHashTraits<UChar32>>;
static CodePointsMap codePointsFromString(StringView stringView)
{
    CodePointsMap result;
    auto graphemeClusters = stringView.graphemeClusters();
    for (auto cluster : graphemeClusters) {
        ASSERT(cluster.length() > 0);
        UChar32 character = 0;
        if (cluster.is8Bit())
            character = cluster[0];
        else
            U16_GET(cluster.characters16(), 0, 0, cluster.length(), character);
        result.add(character);
    }
    return result;
}

ExceptionOr<Vector<std::reference_wrapper<CSSFontFace>>> CSSFontFaceSet::matchingFacesExcludingPreinstalledFonts(const String& fontShorthand, const String& string)
{
    auto font = CSSPropertyParserWorkerSafe::parseFont(fontShorthand, HTMLStandardMode);
    if (!font)
        return Exception { SyntaxError };

    HashSet<AtomString> uniqueFamilies;
    Vector<AtomString> familyOrder;
    for (auto& familyRaw : font->family) {
        AtomString familyAtom;
        WTF::switchOn(familyRaw, [&] (CSSValueID familyKeyword) {
            if (familyKeyword != CSSValueWebkitBody)
                familyAtom = familyNamesData->at(CSSPropertyParserHelpers::genericFontFamilyIndex(familyKeyword));
            else {
                ASSERT(m_owningFontSelector && m_owningFontSelector->scriptExecutionContext());
                familyAtom = m_owningFontSelector->scriptExecutionContext()->settingsValues().fontGenericFamilies.standardFontFamily();
            }
        }, [&] (const String& familyString) {
            familyAtom = familyString;
        });

        if (!familyAtom.isEmpty() && uniqueFamilies.add(familyAtom).isNewEntry)
            familyOrder.append(familyAtom);
    }

    HashSet<CSSFontFace*> resultConstituents;
    auto request = computeFontSelectionRequest(*font);
    for (auto codePoint : codePointsFromString(string)) {
        bool found = false;
        for (auto& family : familyOrder) {
            auto* faces = fontFace(request, family);
            if (!faces)
                continue;
            for (auto& constituentFace : faces->constituentFaces()) {
                if (constituentFace->isLocalFallback())
                    continue;
                if (constituentFace->rangesMatchCodePoint(codePoint)) {
                    resultConstituents.add(constituentFace.ptr());
                    found = true;
                    break;
                }
            }
            if (found)
                break;
        }
    }

    Vector<std::reference_wrapper<CSSFontFace>> result;
    result.reserveInitialCapacity(resultConstituents.size());
    for (auto* constituent : resultConstituents)
        result.uncheckedAppend(*constituent);
    return result;
}

ExceptionOr<bool> CSSFontFaceSet::check(const String& font, const String& text)
{
    auto matchingFaces = this->matchingFacesExcludingPreinstalledFonts(font, text);
    if (matchingFaces.hasException())
        return matchingFaces.releaseException();

    for (auto& face : matchingFaces.releaseReturnValue()) {
        if (face.get().status() == CSSFontFace::Status::Pending
            || face.get().status() == CSSFontFace::Status::Loading)
            return false;
    }
    return true;
}

CSSSegmentedFontFace* CSSFontFaceSet::fontFace(FontSelectionRequest request, const AtomString& family)
{
    auto iterator = m_facesLookupTable.find(family);
    if (iterator == m_facesLookupTable.end())
        return nullptr;
    auto& familyFontFaces = iterator->value;

    auto& segmentedFontFaceCache = m_cache.add(family, FontSelectionHashMap()).iterator->value;

    auto& face = segmentedFontFaceCache.add(request, nullptr).iterator->value;
    if (face)
        return face.get();

    face = CSSSegmentedFontFace::create();

    Vector<std::reference_wrapper<CSSFontFace>, 32> candidateFontFaces;
    for (int i = familyFontFaces.size() - 1; i >= 0; --i) {
        CSSFontFace& candidate = familyFontFaces[i];
        if (auto capabilities = candidate.fontSelectionCapabilities()) {
            if (!isItalic(request.slope) && isItalic(capabilities->slope.minimum))
                continue;
            candidateFontFaces.append(candidate);
        }
    }

    auto localIterator = m_locallyInstalledFacesLookupTable.find(family);
    if (localIterator != m_locallyInstalledFacesLookupTable.end()) {
        for (auto& candidate : localIterator->value) {
            if (auto capabilities = candidate->fontSelectionCapabilities()) {
                if (!isItalic(request.slope) && isItalic(capabilities->slope.minimum))
                    continue;
                candidateFontFaces.append(candidate);
            }
        }
    }

    if (!candidateFontFaces.isEmpty()) {
        Vector<FontSelectionCapabilities> capabilities;
        capabilities.reserveInitialCapacity(candidateFontFaces.size());
        for (auto& face : candidateFontFaces) {
            auto fontSelectionCapabilities = face.get().fontSelectionCapabilities();
            capabilities.uncheckedAppend(*fontSelectionCapabilities);
        }
        FontSelectionAlgorithm fontSelectionAlgorithm(request, capabilities);
        std::stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), [&fontSelectionAlgorithm](const CSSFontFace& first, const CSSFontFace& second) {
            auto firstCapabilities = first.fontSelectionCapabilities();
            auto secondCapabilities = second.fontSelectionCapabilities();
            
            auto stretchDistanceFirst = fontSelectionAlgorithm.stretchDistance(*firstCapabilities).distance;
            auto stretchDistanceSecond = fontSelectionAlgorithm.stretchDistance(*secondCapabilities).distance;
            if (stretchDistanceFirst < stretchDistanceSecond)
                return true;
            if (stretchDistanceFirst > stretchDistanceSecond)
                return false;

            auto styleDistanceFirst = fontSelectionAlgorithm.styleDistance(*firstCapabilities).distance;
            auto styleDistanceSecond = fontSelectionAlgorithm.styleDistance(*secondCapabilities).distance;
            if (styleDistanceFirst < styleDistanceSecond)
                return true;
            if (styleDistanceFirst > styleDistanceSecond)
                return false;

            auto weightDistanceFirst = fontSelectionAlgorithm.weightDistance(*firstCapabilities).distance;
            auto weightDistanceSecond = fontSelectionAlgorithm.weightDistance(*secondCapabilities).distance;
            if (weightDistanceFirst < weightDistanceSecond)
                return true;
            return false;
        });
        CSSFontFace* previousCandidate = nullptr;
        for (auto& candidate : candidateFontFaces) {
            if (&candidate.get() == previousCandidate)
                continue;
            previousCandidate = &candidate.get();
            face->appendFontFace(candidate.get());
        }
    }

    return face.get();
}

void CSSFontFaceSet::fontStateChanged(CSSFontFace& face, CSSFontFace::Status oldState, CSSFontFace::Status newState)
{
    ASSERT(hasFace(face));
    if (oldState == CSSFontFace::Status::Pending) {
        ASSERT(newState == CSSFontFace::Status::Loading);
        incrementActiveCount();
    }
    if (newState == CSSFontFace::Status::Success || newState == CSSFontFace::Status::Failure) {
        ASSERT(oldState == CSSFontFace::Status::Loading || oldState == CSSFontFace::Status::TimedOut);
        m_fontEventClients.forEach([&] (auto& client) {
            client.faceFinished(face, newState);
        });
        decrementActiveCount();
    }
}

void CSSFontFaceSet::fontPropertyChanged(CSSFontFace& face, CSSValueList* oldFamilies)
{
    m_cache.clear();

    if (oldFamilies) {
        removeFromFacesLookupTable(face, *oldFamilies);
        addToFacesLookupTable(face);
    }

    m_fontModifiedObservers.forEach([] (auto& observer) {
        observer();
    });
}

}
