/*
 * Copyright (C) 2014, 2015 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. AND ITS CONTRIBUTORS ``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 ITS 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 "DFANode.h"

#include "DFA.h"
#include <wtf/HashMap.h>

#if ENABLE(CONTENT_EXTENSIONS)

namespace WebCore {

namespace ContentExtensions {

Vector<uint64_t> DFANode::actions(const DFA& dfa) const
{
    // FIXME: Use iterators instead of copying the Vector elements.
    Vector<uint64_t> vector;
    vector.reserveInitialCapacity(m_actionsLength);
    for (uint32_t i = m_actionsStart; i < m_actionsStart + m_actionsLength; ++i)
        vector.uncheckedAppend(dfa.actions[i]);
    return vector;
}

bool DFANode::containsTransition(char transition, const DFA& dfa) const
{
    // Called from DFAMinimizer, this loops though a maximum of 128 transitions, so it's not too slow.
    ASSERT(m_transitionsLength <= 128);
    for (unsigned i = m_transitionsStart; i < m_transitionsStart + m_transitionsLength; ++i) {
        if (dfa.transitionRanges[i].first <= transition
            && dfa.transitionRanges[i].last >= transition)
            return true;
    }
    return false;
}

void DFANode::kill(DFA& dfa)
{
    ASSERT(m_flags != IsKilled);
    m_flags = IsKilled; // Killed nodes don't have any other flags.

    // Invalidate the now-unused memory in the DFA to make finding bugs easier.
    for (unsigned i = m_transitionsStart; i < m_transitionsStart + m_transitionsLength; ++i) {
        dfa.transitionRanges[i] = { -1, -1 };
        dfa.transitionDestinations[i] = std::numeric_limits<uint32_t>::max();
    }
    for (unsigned i = m_actionsStart; i < m_actionsStart + m_actionsLength; ++i)
        dfa.actions[i] = std::numeric_limits<uint64_t>::max();

    m_actionsStart = 0;
    m_actionsLength = 0;
    m_transitionsStart = 0;
    m_transitionsLength = 0;
};

bool DFANode::canUseFallbackTransition(const DFA& dfa) const
{
    // Transitions can contain '\0' if the expression has a end-of-line marker.
    // Fallback transitions cover 1-127. We have to be careful with the first.

    IterableConstRange iterableTransitions = transitions(dfa);
    auto iterator = iterableTransitions.begin();
    auto end = iterableTransitions.end();
    if (iterator == end)
        return false;

    char lastSeenCharacter = 0;
    if (!iterator.first()) {
        lastSeenCharacter = iterator.last();
        if (lastSeenCharacter == 127)
            return true;
        ++iterator;
    }

    for (;iterator != end; ++iterator) {
        ASSERT(iterator.first() > lastSeenCharacter);
        if (iterator.first() != lastSeenCharacter + 1)
            return false;

        if (iterator.range().last == 127)
            return true;
        lastSeenCharacter = iterator.last();
    }
    return false;
}

uint32_t DFANode::bestFallbackTarget(const DFA& dfa) const
{
    ASSERT(canUseFallbackTransition(dfa));

    HashMap<uint32_t, unsigned, DefaultHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> histogram;

    IterableConstRange iterableTransitions = transitions(dfa);
    auto iterator = iterableTransitions.begin();
    auto end = iterableTransitions.end();
    ASSERT_WITH_MESSAGE(iterator != end, "An empty range list cannot use a fallback transition.");

    if (!iterator.first() && !iterator.last())
        ++iterator;
    ASSERT_WITH_MESSAGE(iterator != end, "An empty range list matching only zero cannot use a fallback transition.");

    uint32_t bestTarget = iterator.target();
    unsigned bestTargetScore = !iterator.range().first ? iterator.range().size() - 1 : iterator.range().size();
    histogram.add(bestTarget, bestTargetScore);
    ++iterator;

    for (;iterator != end; ++iterator) {
        unsigned rangeSize = iterator.range().size();
        uint32_t target = iterator.target();
        auto addResult = histogram.add(target, rangeSize);
        if (!addResult.isNewEntry)
            addResult.iterator->value += rangeSize;
        if (addResult.iterator->value > bestTargetScore) {
            bestTargetScore = addResult.iterator->value;
            bestTarget = target;
        }
    }
    return bestTarget;
}

} // namespace ContentExtensions

} // namespace WebCore

#endif // ENABLE(CONTENT_EXTENSIONS)
