/*
    Copyright (C) 2004-2016 Apple Inc. All rights reserved.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "SegmentedString.h"

#include <wtf/text/StringBuilder.h>
#include <wtf/text/TextPosition.h>

namespace WebCore {

inline void SegmentedString::Substring::appendTo(StringBuilder& builder) const
{
    builder.appendSubstring(string, string.length() - length, length);
}

SegmentedString& SegmentedString::operator=(SegmentedString&& other)
{
    m_currentSubstring = WTFMove(other.m_currentSubstring);
    m_otherSubstrings = WTFMove(other.m_otherSubstrings);

    m_isClosed = other.m_isClosed;

    m_currentCharacter = other.m_currentCharacter;

    m_numberOfCharactersConsumedPriorToCurrentSubstring = other.m_numberOfCharactersConsumedPriorToCurrentSubstring;
    m_numberOfCharactersConsumedPriorToCurrentLine = other.m_numberOfCharactersConsumedPriorToCurrentLine;
    m_currentLine = other.m_currentLine;

    m_fastPathFlags = other.m_fastPathFlags;
    m_advanceWithoutUpdatingLineNumberFunction = other.m_advanceWithoutUpdatingLineNumberFunction;
    m_advanceAndUpdateLineNumberFunction = other.m_advanceAndUpdateLineNumberFunction;

    other.clear();

    return *this;
}

unsigned SegmentedString::length() const
{
    unsigned length = m_currentSubstring.length;
    for (auto& substring : m_otherSubstrings)
        length += substring.length;
    return length;
}

void SegmentedString::setExcludeLineNumbers()
{
    if (!m_currentSubstring.doNotExcludeLineNumbers)
        return;
    m_currentSubstring.doNotExcludeLineNumbers = false;
    for (auto& substring : m_otherSubstrings)
        substring.doNotExcludeLineNumbers = false;
    updateAdvanceFunctionPointers();
}

void SegmentedString::clear()
{
    m_currentSubstring.length = 0;
    m_otherSubstrings.clear();

    m_isClosed = false;

    m_currentCharacter = 0;

    m_numberOfCharactersConsumedPriorToCurrentSubstring = 0;
    m_numberOfCharactersConsumedPriorToCurrentLine = 0;
    m_currentLine = 0;

    updateAdvanceFunctionPointersForEmptyString();
}

inline void SegmentedString::appendSubstring(Substring&& substring)
{
    ASSERT(!m_isClosed);
    if (!substring.length)
        return;
    if (m_currentSubstring.length)
        m_otherSubstrings.append(WTFMove(substring));
    else {
        m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed();
        m_currentSubstring = WTFMove(substring);
        m_currentCharacter = m_currentSubstring.currentCharacter();
        updateAdvanceFunctionPointers();
    }
}

void SegmentedString::pushBack(String&& string)
{
    // We never create a substring for an empty string.
    ASSERT(string.length());

    // The new substring we will create won't have the doNotExcludeLineNumbers set appropriately.
    // That was lost when the characters were consumed before pushing them back. But this does
    // not matter, because clients never use this for newlines. Catch that with this assertion.
    ASSERT(!string.contains('\n'));

    // The characters in the string must be previously consumed characters from this segmented string.
    ASSERT(string.length() <= numberOfCharactersConsumed());

    m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed();
    if (m_currentSubstring.length)
        m_otherSubstrings.prepend(WTFMove(m_currentSubstring));
    m_currentSubstring = WTFMove(string);
    m_numberOfCharactersConsumedPriorToCurrentSubstring -= m_currentSubstring.length;
    m_currentCharacter = m_currentSubstring.currentCharacter();
    updateAdvanceFunctionPointers();
}

void SegmentedString::close()
{
    ASSERT(!m_isClosed);
    m_isClosed = true;
}

void SegmentedString::append(const SegmentedString& string)
{
    appendSubstring(Substring { string.m_currentSubstring });
    for (auto& substring : string.m_otherSubstrings)
        m_otherSubstrings.append(substring);
}

void SegmentedString::append(SegmentedString&& string)
{
    appendSubstring(WTFMove(string.m_currentSubstring));
    for (auto& substring : string.m_otherSubstrings)
        m_otherSubstrings.append(WTFMove(substring));
}

void SegmentedString::append(String&& string)
{
    appendSubstring(WTFMove(string));
}

void SegmentedString::append(const String& string)
{
    appendSubstring(String { string });
}

String SegmentedString::toString() const
{
    StringBuilder result;
    m_currentSubstring.appendTo(result);
    for (auto& substring : m_otherSubstrings)
        substring.appendTo(result);
    return result.toString();
}

void SegmentedString::advanceWithoutUpdatingLineNumber16()
{
    m_currentCharacter = *++m_currentSubstring.currentCharacter16;
    decrementAndCheckLength();
}

void SegmentedString::advanceAndUpdateLineNumber16()
{
    ASSERT(m_currentSubstring.doNotExcludeLineNumbers);
    processPossibleNewline();
    m_currentCharacter = *++m_currentSubstring.currentCharacter16;
    decrementAndCheckLength();
}

inline void SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber()
{
    ASSERT(m_currentSubstring.length == 1);
    if (m_otherSubstrings.isEmpty()) {
        m_currentSubstring.length = 0;
        m_currentCharacter = 0;
        updateAdvanceFunctionPointersForEmptyString();
        return;
    }
    m_numberOfCharactersConsumedPriorToCurrentSubstring += m_currentSubstring.numberOfCharactersConsumed();
    m_currentSubstring = m_otherSubstrings.takeFirst();
    // If we've previously consumed some characters of the non-current string, we now account for those
    // characters as part of the current string, not as part of "prior to current string."
    m_numberOfCharactersConsumedPriorToCurrentSubstring -= m_currentSubstring.numberOfCharactersConsumed();
    m_currentCharacter = m_currentSubstring.currentCharacter();
    updateAdvanceFunctionPointers();
}

void SegmentedString::advancePastSingleCharacterSubstring()
{
    ASSERT(m_currentSubstring.length == 1);
    ASSERT(m_currentSubstring.doNotExcludeLineNumbers);
    processPossibleNewline();
    advancePastSingleCharacterSubstringWithoutUpdatingLineNumber();
}

void SegmentedString::advanceEmpty()
{
    ASSERT(!m_currentSubstring.length);
    ASSERT(m_otherSubstrings.isEmpty());
    ASSERT(!m_currentCharacter);
}

void SegmentedString::updateAdvanceFunctionPointersForSingleCharacterSubstring()
{
    ASSERT(m_currentSubstring.length == 1);
    m_fastPathFlags = NoFastPath;
    m_advanceWithoutUpdatingLineNumberFunction = &SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber;
    if (m_currentSubstring.doNotExcludeLineNumbers)
        m_advanceAndUpdateLineNumberFunction = &SegmentedString::advancePastSingleCharacterSubstring;
    else
        m_advanceAndUpdateLineNumberFunction = &SegmentedString::advancePastSingleCharacterSubstringWithoutUpdatingLineNumber;
}

OrdinalNumber SegmentedString::currentLine() const
{
    return OrdinalNumber::fromZeroBasedInt(m_currentLine);
}

OrdinalNumber SegmentedString::currentColumn() const
{
    return OrdinalNumber::fromZeroBasedInt(numberOfCharactersConsumed() - m_numberOfCharactersConsumedPriorToCurrentLine);
}

void SegmentedString::setCurrentPosition(OrdinalNumber line, OrdinalNumber columnAftreProlog, int prologLength)
{
    m_currentLine = line.zeroBasedInt();
    m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + prologLength - columnAftreProlog.zeroBasedInt();
}

SegmentedString::AdvancePastResult SegmentedString::advancePastSlowCase(const char* literal, bool lettersIgnoringASCIICase)
{
    constexpr unsigned maxLength = 10;
    ASSERT(!strchr(literal, '\n'));
    auto length = strlen(literal);
    ASSERT(length <= maxLength);
    if (length > this->length())
        return NotEnoughCharacters;
    UChar consumedCharacters[maxLength];
    for (unsigned i = 0; i < length; ++i) {
        auto character = m_currentCharacter;
        if (characterMismatch(character, literal[i], lettersIgnoringASCIICase)) {
            if (i)
                pushBack(String { consumedCharacters, i });
            return DidNotMatch;
        }
        advancePastNonNewline();
        consumedCharacters[i] = character;
    }
    return DidMatch;
}

void SegmentedString::updateAdvanceFunctionPointersForEmptyString()
{
    ASSERT(!m_currentSubstring.length);
    ASSERT(m_otherSubstrings.isEmpty());
    ASSERT(!m_currentCharacter);
    m_fastPathFlags = NoFastPath;
    m_advanceWithoutUpdatingLineNumberFunction = &SegmentedString::advanceEmpty;
    m_advanceAndUpdateLineNumberFunction = &SegmentedString::advanceEmpty;
}

}
