/*
 * 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 {
public:
    IDBKeyData()
        : m_type(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 = KeyType::Min;
        result.m_isNull = false;
        return result;
    }

    static IDBKeyData maximum()
    {
        IDBKeyData result;
        result.m_type = 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 std::optional<IDBKeyData> decode(Decoder&);
    
#if !LOG_DISABLED
    WEBCORE_EXPORT String loggingString() const;
#endif

    bool isNull() const { return m_isNull; }
    bool isValid() const { return m_type != KeyType::Invalid; }
    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 KeyType::Invalid:
        case KeyType::Max:
        case KeyType::Min:
            break;
        case KeyType::Number:
        case KeyType::Date:
            hashCodes.append(StringHasher::hashMemory<sizeof(double)>(&WTF::get<double>(m_value)));
            break;
        case KeyType::String:
            hashCodes.append(StringHash::hash(WTF::get<String>(m_value)));
            break;
        case 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 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 == KeyType::String);
        return WTF::get<String>(m_value);
    }

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

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

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

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

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

    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 KeyType::Invalid:
    case KeyType::Max:
    case KeyType::Min:
        break;
    case KeyType::Array:
        encoder << WTF::get<Vector<IDBKeyData>>(m_value);
        break;
    case KeyType::Binary:
        encoder << WTF::get<ThreadSafeDataBuffer>(m_value);
        break;
    case KeyType::String:
        encoder << WTF::get<String>(m_value);
        break;
    case KeyType::Date:
    case KeyType::Number:
        encoder << WTF::get<double>(m_value);
        break;
    }
}

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

    if (keyData.m_isNull)
        return WTFMove(keyData);

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

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

    return WTFMove(keyData);
}

using IDBKeyDataSet = StdSet<IDBKeyData>;

} // namespace WebCore

#endif // ENABLE(INDEXED_DATABASE)
