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

#pragma once

#if ENABLE(INDEXED_DATABASE)

#include "IDBKey.h"
#include <wtf/StdSet.h>
#include <wtf/Variant.h>
#include <wtf/text/StringHash.h>

namespace WebCore {

class KeyedDecoder;
class KeyedEncoder;

class IDBKeyData {
    WTF_MAKE_FAST_ALLOCATED;
public:
    IDBKeyData()
        : m_type(IndexedDB::KeyType::Invalid)
        , m_isNull(true)
    {
    }

    WEBCORE_EXPORT IDBKeyData(const IDBKey*);

    enum IsolatedCopyTag { IsolatedCopy };
    IDBKeyData(const IDBKeyData&, IsolatedCopyTag);

    static IDBKeyData minimum()
    {
        IDBKeyData result;
        result.m_type = IndexedDB::KeyType::Min;
        result.m_isNull = false;
        return result;
    }

    static IDBKeyData maximum()
    {
        IDBKeyData result;
        result.m_type = IndexedDB::KeyType::Max;
        result.m_isNull = false;
        return result;
    }

    WEBCORE_EXPORT RefPtr<IDBKey> maybeCreateIDBKey() const;

    IDBKeyData isolatedCopy() const;

    WEBCORE_EXPORT void encode(KeyedEncoder&) const;
    WEBCORE_EXPORT static bool decode(KeyedDecoder&, IDBKeyData&);

    // compare() has the same semantics as strcmp().
    //   - Returns negative if this IDBKeyData is less than other.
    //   - Returns positive if this IDBKeyData is greater than other.
    //   - Returns zero if this IDBKeyData is equal to other.
    WEBCORE_EXPORT int compare(const IDBKeyData& other) const;

    void setArrayValue(const Vector<IDBKeyData>&);
    void setBinaryValue(const ThreadSafeDataBuffer&);
    void setStringValue(const String&);
    void setDateValue(double);
    WEBCORE_EXPORT void setNumberValue(double);

    template<class Encoder> void encode(Encoder&) const;
    template<class Decoder> static Optional<IDBKeyData> decode(Decoder&);
    
#if !LOG_DISABLED
    WEBCORE_EXPORT String loggingString() const;
#endif

    bool isNull() const { return m_isNull; }
    bool isValid() const;
    IndexedDB::KeyType type() const { return m_type; }

    bool operator<(const IDBKeyData&) const;
    bool operator>(const IDBKeyData& other) const
    {
        return !(*this < other) && !(*this == other);
    }

    bool operator<=(const IDBKeyData& other) const
    {
        return !(*this > other);
    }

    bool operator>=(const IDBKeyData& other) const
    {
        return !(*this < other);
    }

    bool operator==(const IDBKeyData& other) const;
    bool operator!=(const IDBKeyData& other) const
    {
        return !(*this == other);
    }

    unsigned hash() const
    {
        Vector<unsigned> hashCodes;
        hashCodes.append(static_cast<unsigned>(m_type));
        hashCodes.append(m_isNull ? 1 : 0);
        hashCodes.append(m_isDeletedValue ? 1 : 0);
        switch (m_type) {
        case IndexedDB::KeyType::Invalid:
        case IndexedDB::KeyType::Max:
        case IndexedDB::KeyType::Min:
            break;
        case IndexedDB::KeyType::Number:
        case IndexedDB::KeyType::Date:
            hashCodes.append(StringHasher::hashMemory<sizeof(double)>(&WTF::get<double>(m_value)));
            break;
        case IndexedDB::KeyType::String:
            hashCodes.append(StringHash::hash(WTF::get<String>(m_value)));
            break;
        case IndexedDB::KeyType::Binary: {
            auto* data = WTF::get<ThreadSafeDataBuffer>(m_value).data();
            if (!data)
                hashCodes.append(0);
            else
                hashCodes.append(StringHasher::hashMemory(data->data(), data->size()));
            break;
        }
        case IndexedDB::KeyType::Array:
            for (auto& key : WTF::get<Vector<IDBKeyData>>(m_value))
                hashCodes.append(key.hash());
            break;
        }

        return StringHasher::hashMemory(hashCodes.data(), hashCodes.size() * sizeof(unsigned));
    }

    static IDBKeyData deletedValue();
    bool isDeletedValue() const { return m_isDeletedValue; }

    String string() const
    {
        ASSERT(m_type == IndexedDB::KeyType::String);
        return WTF::get<String>(m_value);
    }

    double date() const
    {
        ASSERT(m_type == IndexedDB::KeyType::Date);
        return WTF::get<double>(m_value);
    }

    double number() const
    {
        ASSERT(m_type == IndexedDB::KeyType::Number);
        return WTF::get<double>(m_value);
    }

    const ThreadSafeDataBuffer& binary() const
    {
        ASSERT(m_type == IndexedDB::KeyType::Binary);
        return WTF::get<ThreadSafeDataBuffer>(m_value);
    }

    const Vector<IDBKeyData>& array() const
    {
        ASSERT(m_type == IndexedDB::KeyType::Array);
        return WTF::get<Vector<IDBKeyData>>(m_value);
    }

private:
    static void isolatedCopy(const IDBKeyData& source, IDBKeyData& destination);

    IndexedDB::KeyType m_type;
    Variant<Vector<IDBKeyData>, String, double, ThreadSafeDataBuffer> m_value;

    bool m_isNull { false };
    bool m_isDeletedValue { false };
};

struct IDBKeyDataHash {
    static unsigned hash(const IDBKeyData& a) { return a.hash(); }
    static bool equal(const IDBKeyData& a, const IDBKeyData& b) { return a == b; }
    static const bool safeToCompareToEmptyOrDeleted = false;
};

struct IDBKeyDataHashTraits : public WTF::CustomHashTraits<IDBKeyData> {
    static const bool emptyValueIsZero = false;
    static const bool hasIsEmptyValueFunction = true;

    static void constructDeletedValue(IDBKeyData& key)
    {
        new (&key) IDBKeyData;
        key = IDBKeyData::deletedValue();
    }

    static bool isDeletedValue(const IDBKeyData& key)
    {
        return key.isDeletedValue();
    }

    static IDBKeyData emptyValue()
    {
        return IDBKeyData();
    }

    static bool isEmptyValue(const IDBKeyData& key)
    {
        return key.isNull();
    }
};

template<class Encoder>
void IDBKeyData::encode(Encoder& encoder) const
{
    encoder << m_isNull;
    if (m_isNull)
        return;

    encoder.encodeEnum(m_type);

    switch (m_type) {
    case IndexedDB::KeyType::Invalid:
    case IndexedDB::KeyType::Max:
    case IndexedDB::KeyType::Min:
        break;
    case IndexedDB::KeyType::Array:
        encoder << WTF::get<Vector<IDBKeyData>>(m_value);
        break;
    case IndexedDB::KeyType::Binary:
        encoder << WTF::get<ThreadSafeDataBuffer>(m_value);
        break;
    case IndexedDB::KeyType::String:
        encoder << WTF::get<String>(m_value);
        break;
    case IndexedDB::KeyType::Date:
    case IndexedDB::KeyType::Number:
        encoder << WTF::get<double>(m_value);
        break;
    }
}

template<class Decoder>
Optional<IDBKeyData> IDBKeyData::decode(Decoder& decoder)
{
    IDBKeyData keyData;
    if (!decoder.decode(keyData.m_isNull))
        return WTF::nullopt;

    if (keyData.m_isNull)
        return keyData;

    if (!decoder.decodeEnum(keyData.m_type))
        return WTF::nullopt;

    switch (keyData.m_type) {
    case IndexedDB::KeyType::Invalid:
    case IndexedDB::KeyType::Max:
    case IndexedDB::KeyType::Min:
        break;
    case IndexedDB::KeyType::Array:
        keyData.m_value = Vector<IDBKeyData>();
        if (!decoder.decode(WTF::get<Vector<IDBKeyData>>(keyData.m_value)))
            return WTF::nullopt;
        break;
    case IndexedDB::KeyType::Binary:
        keyData.m_value = ThreadSafeDataBuffer();
        if (!decoder.decode(WTF::get<ThreadSafeDataBuffer>(keyData.m_value)))
            return WTF::nullopt;
        break;
    case IndexedDB::KeyType::String:
        keyData.m_value = String();
        if (!decoder.decode(WTF::get<String>(keyData.m_value)))
            return WTF::nullopt;
        break;
    case IndexedDB::KeyType::Date:
    case IndexedDB::KeyType::Number:
        keyData.m_value = 0.0;
        if (!decoder.decode(WTF::get<double>(keyData.m_value)))
            return WTF::nullopt;
        break;
    }

    return keyData;
}

using IDBKeyDataSet = StdSet<IDBKeyData>;

} // namespace WebCore

#endif // ENABLE(INDEXED_DATABASE)
