/*
 * Copyright (C) 2004-2006, 2008, 2014-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.
 *
 */

#ifndef AtomicString_h
#define AtomicString_h

#include <utility>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/AtomicStringImpl.h>
#include <wtf/text/IntegerToStringConversion.h>
#include <wtf/text/WTFString.h>

// Define 'NO_IMPLICIT_ATOMICSTRING' before including this header,
// to disallow (expensive) implicit String-->AtomicString conversions.
#ifdef NO_IMPLICIT_ATOMICSTRING
#define ATOMICSTRING_CONVERSION explicit
#else
#define ATOMICSTRING_CONVERSION
#endif

namespace WTF {

struct AtomicStringHash;

class AtomicString {
public:
    WTF_EXPORT_PRIVATE static void init();

    AtomicString();
    AtomicString(const LChar*);
    AtomicString(const char*);
    AtomicString(const LChar*, unsigned length);
    AtomicString(const UChar*, unsigned length);
    AtomicString(const UChar*);

    template<size_t inlineCapacity>
    explicit AtomicString(const Vector<UChar, inlineCapacity>& characters)
        : m_string(AtomicStringImpl::add(characters.data(), characters.size()))
    {
    }

    AtomicString(AtomicStringImpl*);
    AtomicString(RefPtr<AtomicStringImpl>&&);
    ATOMICSTRING_CONVERSION AtomicString(StringImpl*);
    ATOMICSTRING_CONVERSION AtomicString(const String&);
    AtomicString(StringImpl* baseString, unsigned start, unsigned length);

    // FIXME: AtomicString doesn’t always have AtomicStringImpl, so one of those two names needs to change..
    AtomicString(UniquedStringImpl* uid);

    enum ConstructFromLiteralTag { ConstructFromLiteral };
    AtomicString(const char* characters, unsigned length, ConstructFromLiteralTag)
        : m_string(AtomicStringImpl::addLiteral(characters, length))
    {
    }

    template<unsigned characterCount>
    ALWAYS_INLINE AtomicString(const char (&characters)[characterCount], ConstructFromLiteralTag)
        : m_string(AtomicStringImpl::addLiteral(characters, characterCount - 1))
    {
        COMPILE_ASSERT(characterCount > 1, AtomicStringFromLiteralNotEmpty);
        COMPILE_ASSERT((characterCount - 1 <= ((unsigned(~0) - sizeof(StringImpl)) / sizeof(LChar))), AtomicStringFromLiteralCannotOverflow);
    }

    // We have to declare the copy constructor and copy assignment operator as well, otherwise
    // they'll be implicitly deleted by adding the move constructor and move assignment operator.
    AtomicString(const AtomicString& other) : m_string(other.m_string) { }
    AtomicString(AtomicString&& other) : m_string(WTFMove(other.m_string)) { }
    AtomicString& operator=(const AtomicString& other) { m_string = other.m_string; return *this; }
    AtomicString& operator=(AtomicString&& other) { m_string = WTFMove(other.m_string); return *this; }

    // Hash table deleted values, which are only constructed and never copied or destroyed.
    AtomicString(WTF::HashTableDeletedValueType) : m_string(WTF::HashTableDeletedValue) { }
    bool isHashTableDeletedValue() const { return m_string.isHashTableDeletedValue(); }

    unsigned existingHash() const { return isNull() ? 0 : impl()->existingHash(); }

    operator const String&() const { return m_string; }
    const String& string() const { return m_string; };

    AtomicStringImpl* impl() const { return static_cast<AtomicStringImpl *>(m_string.impl()); }

    bool is8Bit() const { return m_string.is8Bit(); }
    const LChar* characters8() const { return m_string.characters8(); }
    const UChar* characters16() const { return m_string.characters16(); }
    unsigned length() const { return m_string.length(); }

    UChar operator[](unsigned int i) const { return m_string[i]; }

    WTF_EXPORT_STRING_API static AtomicString number(int);
    WTF_EXPORT_STRING_API static AtomicString number(unsigned);
    WTF_EXPORT_STRING_API static AtomicString number(unsigned long);
    WTF_EXPORT_STRING_API static AtomicString number(unsigned long long);
    WTF_EXPORT_STRING_API static AtomicString number(double);
    // If we need more overloads of the number function, we can add all the others that String has, but these seem to do for now.

    bool contains(UChar c) const { return m_string.contains(c); }
    bool contains(const LChar* s, bool caseSensitive = true) const
        { return m_string.contains(s, caseSensitive); }
    bool contains(const String& s) const
        { return m_string.contains(s); }
    bool contains(const String& s, bool caseSensitive) const
        { return m_string.contains(s, caseSensitive); }
    bool containsIgnoringASCIICase(const String& s) const
        { return m_string.containsIgnoringASCIICase(s); }

    size_t find(UChar c, unsigned start = 0) const { return m_string.find(c, start); }
    size_t find(const LChar* s, unsigned start = 0, bool caseSentitive = true) const
        { return m_string.find(s, start, caseSentitive); }
    size_t find(const String& s, unsigned start = 0, bool caseSentitive = true) const
        { return m_string.find(s, start, caseSentitive); }
    size_t findIgnoringASCIICase(const String& s) const
        { return m_string.findIgnoringASCIICase(s); }
    size_t findIgnoringASCIICase(const String& s, unsigned startOffset) const
        { return m_string.findIgnoringASCIICase(s, startOffset); }
    size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) const
        { return m_string.find(matchFunction, start); }

    bool startsWith(const String& s) const
        { return m_string.startsWith(s); }
    bool startsWithIgnoringASCIICase(const String& s) const
        { return m_string.startsWithIgnoringASCIICase(s); }
    bool startsWith(const String& s, bool caseSensitive) const
        { return m_string.startsWith(s, caseSensitive); }
    bool startsWith(UChar character) const
        { return m_string.startsWith(character); }
    template<unsigned matchLength>
    bool startsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const
        { return m_string.startsWith<matchLength>(prefix, caseSensitive); }

    bool endsWith(const String& s) const
        { return m_string.endsWith(s); }
    bool endsWithIgnoringASCIICase(const String& s) const
        { return m_string.endsWithIgnoringASCIICase(s); }
    bool endsWith(const String& s, bool caseSensitive) const
        { return m_string.endsWith(s, caseSensitive); }
    bool endsWith(UChar character) const
        { return m_string.endsWith(character); }
    template<unsigned matchLength>
    bool endsWith(const char (&prefix)[matchLength], bool caseSensitive = true) const
        { return m_string.endsWith<matchLength>(prefix, caseSensitive); }

    WTF_EXPORT_STRING_API AtomicString convertToASCIILowercase() const;
    WTF_EXPORT_STRING_API AtomicString convertToASCIIUppercase() const;

    int toInt(bool* ok = 0) const { return m_string.toInt(ok); }
    double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); }
    float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); }
    bool percentage(int& p) const { return m_string.percentage(p); }

    bool isNull() const { return m_string.isNull(); }
    bool isEmpty() const { return m_string.isEmpty(); }

#if USE(CF)
    AtomicString(CFStringRef);
#endif
#ifdef __OBJC__
    AtomicString(NSString*);
    operator NSString*() const { return m_string; }
#endif

    // AtomicString::fromUTF8 will return a null string if
    // the input data contains invalid UTF-8 sequences.
    static AtomicString fromUTF8(const char*, size_t);
    static AtomicString fromUTF8(const char*);

#ifndef NDEBUG
    void show() const;
#endif

private:
    // The explicit constructors with AtomicString::ConstructFromLiteral must be used for literals.
    AtomicString(ASCIILiteral);

    enum class CaseConvertType { Upper, Lower };
    template<CaseConvertType> AtomicString convertASCIICase() const;

    WTF_EXPORT_STRING_API static AtomicString fromUTF8Internal(const char*, const char*);

    String m_string;
};

static_assert(sizeof(AtomicString) == sizeof(String), "AtomicString and String must be same size!");

inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); }
bool operator==(const AtomicString&, const LChar*);
inline bool operator==(const AtomicString& a, const char* b) { return WTF::equal(a.impl(), reinterpret_cast<const LChar*>(b)); }
inline bool operator==(const AtomicString& a, const Vector<UChar>& b) { return a.impl() && equal(a.impl(), b.data(), b.size()); }    
inline bool operator==(const AtomicString& a, const String& b) { return equal(a.impl(), b.impl()); }
inline bool operator==(const LChar* a, const AtomicString& b) { return b == a; }
inline bool operator==(const String& a, const AtomicString& b) { return equal(a.impl(), b.impl()); }
inline bool operator==(const Vector<UChar>& a, const AtomicString& b) { return b == a; }

inline bool operator!=(const AtomicString& a, const AtomicString& b) { return a.impl() != b.impl(); }
inline bool operator!=(const AtomicString& a, const LChar* b) { return !(a == b); }
inline bool operator!=(const AtomicString& a, const char* b) { return !(a == b); }
inline bool operator!=(const AtomicString& a, const String& b) { return !equal(a.impl(), b.impl()); }
inline bool operator!=(const AtomicString& a, const Vector<UChar>& b) { return !(a == b); }
inline bool operator!=(const LChar* a, const AtomicString& b) { return !(b == a); }
inline bool operator!=(const String& a, const AtomicString& b) { return !equal(a.impl(), b.impl()); }
inline bool operator!=(const Vector<UChar>& a, const AtomicString& b) { return !(a == b); }

bool equalIgnoringASCIICase(const AtomicString&, const AtomicString&);
bool equalIgnoringASCIICase(const AtomicString&, const String&);
bool equalIgnoringASCIICase(const String&, const AtomicString&);
bool equalIgnoringASCIICase(const AtomicString&, const char*);

template<unsigned length> bool equalLettersIgnoringASCIICase(const AtomicString&, const char (&lowercaseLetters)[length]);

inline AtomicString::AtomicString()
{
}

inline AtomicString::AtomicString(const LChar* s)
    : m_string(AtomicStringImpl::add(s))
{
}

inline AtomicString::AtomicString(const char* s)
    : m_string(AtomicStringImpl::add(s))
{
}

inline AtomicString::AtomicString(const LChar* s, unsigned length)
    : m_string(AtomicStringImpl::add(s, length))
{
}

inline AtomicString::AtomicString(const UChar* s, unsigned length)
    : m_string(AtomicStringImpl::add(s, length))
{
}

inline AtomicString::AtomicString(const UChar* s)
    : m_string(AtomicStringImpl::add(s))
{
}

inline AtomicString::AtomicString(AtomicStringImpl* imp)
    : m_string(imp)
{
}

inline AtomicString::AtomicString(RefPtr<AtomicStringImpl>&& imp)
    : m_string(WTFMove(imp))
{
}

inline AtomicString::AtomicString(StringImpl* imp)
    : m_string(AtomicStringImpl::add(imp))
{
}

inline AtomicString::AtomicString(const String& s)
    : m_string(AtomicStringImpl::add(s.impl()))
{
}

inline AtomicString::AtomicString(StringImpl* baseString, unsigned start, unsigned length)
    : m_string(AtomicStringImpl::add(baseString, start, length))
{
}

inline AtomicString::AtomicString(UniquedStringImpl* uid)
    : m_string(uid)
{
}

#if USE(CF)
inline AtomicString::AtomicString(CFStringRef s)
    :  m_string(AtomicStringImpl::add(s))
{
}
#endif

#ifdef __OBJC__
inline AtomicString::AtomicString(NSString* s)
    : m_string(AtomicStringImpl::add((__bridge CFStringRef)s))
{
}
#endif

// Define external global variables for the commonly used atomic strings.
// These are only usable from the main thread.
extern WTF_EXPORTDATA LazyNeverDestroyed<AtomicString> nullAtomData;
extern WTF_EXPORTDATA LazyNeverDestroyed<AtomicString> emptyAtomData;
extern WTF_EXPORTDATA LazyNeverDestroyed<AtomicString> starAtomData;
extern WTF_EXPORTDATA LazyNeverDestroyed<AtomicString> xmlAtomData;
extern WTF_EXPORTDATA LazyNeverDestroyed<AtomicString> xmlnsAtomData;

inline const AtomicString& nullAtom() { return nullAtomData.get(); }
inline const AtomicString& emptyAtom() { return emptyAtomData.get(); }
inline const AtomicString& starAtom() { return starAtomData.get(); }
inline const AtomicString& xmlAtom() { return xmlAtomData.get(); }
inline const AtomicString& xmlnsAtom() { return xmlnsAtomData.get(); }

inline AtomicString AtomicString::fromUTF8(const char* characters, size_t length)
{
    if (!characters)
        return nullAtom();
    if (!length)
        return emptyAtom();
    return fromUTF8Internal(characters, characters + length);
}

inline AtomicString AtomicString::fromUTF8(const char* characters)
{
    if (!characters)
        return nullAtom();
    if (!*characters)
        return emptyAtom();
    return fromUTF8Internal(characters, nullptr);
}

// AtomicStringHash is the default hash for AtomicString
template<typename T> struct DefaultHash;
template<> struct DefaultHash<AtomicString> {
    typedef AtomicStringHash Hash;
};

template<unsigned length> inline bool equalLettersIgnoringASCIICase(const AtomicString& string, const char (&lowercaseLetters)[length])
{
    return equalLettersIgnoringASCIICase(string.string(), lowercaseLetters);
}

inline bool equalIgnoringASCIICase(const AtomicString& a, const AtomicString& b)
{
    return equalIgnoringASCIICase(a.string(), b.string());
}

inline bool equalIgnoringASCIICase(const AtomicString& a, const String& b)
{
    return equalIgnoringASCIICase(a.string(), b);
}

inline bool equalIgnoringASCIICase(const String& a, const AtomicString& b)
{
    return equalIgnoringASCIICase(a, b.string());
}

inline bool equalIgnoringASCIICase(const AtomicString& a, const char* b)
{
    return equalIgnoringASCIICase(a.string(), b);
}

template<> struct IntegerToStringConversionTrait<AtomicString> {
    using ReturnType = AtomicString;
    using AdditionalArgumentType = void;
    static AtomicString flush(LChar* characters, unsigned length, void*) { return { characters, length }; }
};

} // namespace WTF

#ifndef ATOMICSTRING_HIDE_GLOBALS
using WTF::AtomicString;
using WTF::nullAtom;
using WTF::emptyAtom;
using WTF::starAtom;
using WTF::xmlAtom;
using WTF::xmlnsAtom;
#endif

#include <wtf/text/StringConcatenate.h>

#endif // AtomicString_h
