/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// When the platform supports STL, the functions are implemented using a
// templated spreadsort algorithm (http://sourceforge.net/projects/spreadsort/),
// part of the Boost C++ library collection. Otherwise, the C standard library's
// qsort() will be used.

#include "sort.h"

#include <cassert>
#include <cstring>  // memcpy
#include <new>      // nothrow new

#ifdef NO_STL
#include <cstdlib>      // qsort
#else
#include <algorithm>    // std::sort
#include <vector>
#include "spreadsort.hpp" // TODO (ajm) upgrade to spreadsortv2.
#endif

#ifdef NO_STL
#define COMPARE_DEREFERENCED(XT, YT)        \
    do                                      \
    {                                       \
        if ((XT) > (YT))                    \
        {                                   \
            return 1;                       \
        }                                   \
        else if ((XT) < (YT))               \
        {                                   \
            return -1;                      \
        }                                   \
                                            \
        return 0;                           \
    }                                       \
    while(0)

#define COMPARE_FOR_QSORT(X, Y, TYPE)                               \
    do                                                              \
    {                                                               \
        TYPE xT = static_cast<TYPE>(*static_cast<const TYPE*>(X));  \
        TYPE yT = static_cast<TYPE>(*static_cast<const TYPE*>(Y));  \
        COMPARE_DEREFERENCED(xT, yT);                               \
    }                                                               \
    while(0)

#define COMPARE_KEY_FOR_QSORT(SORT_KEY_X, SORT_KEY_Y, TYPE)         \
    do                                                              \
    {                                                               \
        TYPE xT = static_cast<TYPE>(*static_cast<TYPE*>             \
            (static_cast<const SortKey*>(SORT_KEY_X)->key));        \
        TYPE yT = static_cast<TYPE>(*static_cast<TYPE*>             \
            (static_cast<const SortKey*>(SORT_KEY_Y)->key));        \
        COMPARE_DEREFERENCED(xT, yT);                               \
    }                                                               \
    while(0)

#define KEY_QSORT(SORT_KEY, KEY, NUM_OF_ELEMENTS, KEY_TYPE, COMPARE_FUNC)     \
    do                                                                        \
    {                                                                         \
        KEY_TYPE* keyT = (KEY_TYPE*)(key);                                    \
        for (WebRtc_UWord32 i = 0; i < (NUM_OF_ELEMENTS); i++)                \
        {                                                                     \
            ptrSortKey[i].key = &keyT[i];                                     \
            ptrSortKey[i].index = i;                                          \
        }                                                                     \
                                                                              \
        qsort((SORT_KEY), (NUM_OF_ELEMENTS), sizeof(SortKey), (COMPARE_FUNC));\
    }                                                                         \
    while(0)
#endif

namespace webrtc
{
#ifdef NO_STL
    struct SortKey
    {
        void* key;
        WebRtc_UWord32 index;
    };
#else
    template<typename KeyType>
    struct SortKey
    {
        KeyType key;
        WebRtc_UWord32 index;
    };
#endif

    namespace // Unnamed namespace provides internal linkage.
    {
#ifdef NO_STL
        int CompareWord8(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_Word8);
        }

        int CompareUWord8(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_UWord8);
        }

        int CompareWord16(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_Word16);
        }

        int CompareUWord16(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_UWord16);
        }

        int CompareWord32(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_Word32);
        }

        int CompareUWord32(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_UWord32);
        }

        int CompareWord64(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_Word64);
        }

        int CompareUWord64(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, WebRtc_UWord64);
        }

        int CompareFloat32(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, float);
        }

        int CompareFloat64(const void* x, const void* y)
        {
            COMPARE_FOR_QSORT(x, y, double);
        }

        int CompareKeyWord8(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word8);
        }

        int CompareKeyUWord8(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord8);
        }

        int CompareKeyWord16(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word16);
        }

        int CompareKeyUWord16(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord16);
        }

        int CompareKeyWord32(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word32);
        }

        int CompareKeyUWord32(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord32);
        }

        int CompareKeyWord64(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_Word64);
        }

        int CompareKeyUWord64(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, WebRtc_UWord64);
        }

        int CompareKeyFloat32(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, float);
        }

        int CompareKeyFloat64(const void* sortKeyX, const void* sortKeyY)
        {
            COMPARE_KEY_FOR_QSORT(sortKeyX, sortKeyY, double);
        }
#else
        template <typename KeyType>
        struct KeyLessThan
        {
            bool operator()(const SortKey<KeyType>& sortKeyX,
                const SortKey<KeyType>& sortKeyY) const
            {
                return sortKeyX.key < sortKeyY.key;
            }
        };

        template <typename KeyType>
        struct KeyRightShift
        {
            KeyType operator()(const SortKey<KeyType>& sortKey,
                const unsigned offset) const
            {
                return sortKey.key >> offset;
            }
        };

        template <typename DataType>
        inline void IntegerSort(void* data, WebRtc_UWord32 numOfElements)
        {
            DataType* dataT = static_cast<DataType*>(data);
            boost::integer_sort(dataT, dataT + numOfElements);
        }

        template <typename DataType, typename IntegerType>
        inline void FloatSort(void* data, WebRtc_UWord32 numOfElements)
        {
            DataType* dataT = static_cast<DataType*>(data);
            IntegerType cVal = 0;
            boost::float_sort_cast(dataT, dataT + numOfElements, cVal);
        }

        template <typename DataType>
        inline void StdSort(void* data, WebRtc_UWord32 numOfElements)
        {
            DataType* dataT = static_cast<DataType*>(data);
            std::sort(dataT, dataT + numOfElements);
        }

        template<typename KeyType>
        inline WebRtc_Word32 SetupKeySort(void* key,
                                          SortKey<KeyType>*& ptrSortKey,
                                          WebRtc_UWord32 numOfElements)
        {
            ptrSortKey = new(std::nothrow) SortKey<KeyType>[numOfElements];
            if (ptrSortKey == NULL)
            {
                return -1;
            }

            KeyType* keyT = static_cast<KeyType*>(key);
            for (WebRtc_UWord32 i = 0; i < numOfElements; i++)
            {
                ptrSortKey[i].key = keyT[i];
                ptrSortKey[i].index = i;
            }

            return 0;
        }

        template<typename KeyType>
        inline WebRtc_Word32 TeardownKeySort(void* data,
                                             SortKey<KeyType>* ptrSortKey,
            WebRtc_UWord32 numOfElements, WebRtc_UWord32 sizeOfElement)
        {
            WebRtc_UWord8* ptrData = static_cast<WebRtc_UWord8*>(data);
            WebRtc_UWord8* ptrDataSorted = new(std::nothrow) WebRtc_UWord8
                [numOfElements * sizeOfElement];
            if (ptrDataSorted == NULL)
            {
                return -1;
            }

            for (WebRtc_UWord32 i = 0; i < numOfElements; i++)
            {
                memcpy(ptrDataSorted + i * sizeOfElement, ptrData +
                       ptrSortKey[i].index * sizeOfElement, sizeOfElement);
            }
            memcpy(ptrData, ptrDataSorted, numOfElements * sizeOfElement);
            delete[] ptrSortKey;
            delete[] ptrDataSorted;
            return 0;
        }

        template<typename KeyType>
        inline WebRtc_Word32 IntegerKeySort(void* data, void* key,
                                            WebRtc_UWord32 numOfElements,
                                            WebRtc_UWord32 sizeOfElement)
        {
            SortKey<KeyType>* ptrSortKey;
            if (SetupKeySort<KeyType>(key, ptrSortKey, numOfElements) != 0)
            {
                return -1;
            }

            boost::integer_sort(ptrSortKey, ptrSortKey + numOfElements,
                KeyRightShift<KeyType>(), KeyLessThan<KeyType>());

            if (TeardownKeySort<KeyType>(data, ptrSortKey, numOfElements,
                    sizeOfElement) != 0)
            {
                return -1;
            }

            return 0;
        }

        template<typename KeyType>
        inline WebRtc_Word32 StdKeySort(void* data, void* key,
                                        WebRtc_UWord32 numOfElements,
                                        WebRtc_UWord32 sizeOfElement)
        {
            SortKey<KeyType>* ptrSortKey;
            if (SetupKeySort<KeyType>(key, ptrSortKey, numOfElements) != 0)
            {
                return -1;
            }

            std::sort(ptrSortKey, ptrSortKey + numOfElements,
                KeyLessThan<KeyType>());

            if (TeardownKeySort<KeyType>(data, ptrSortKey, numOfElements,
                    sizeOfElement) != 0)
            {
                return -1;
            }

            return 0;
        }
#endif
    }

    WebRtc_Word32 Sort(void* data, WebRtc_UWord32 numOfElements, Type type)
    {
        if (data == NULL)
        {
            return -1;
        }

#ifdef NO_STL
        switch (type)
        {
        case TYPE_Word8:
            qsort(data, numOfElements, sizeof(WebRtc_Word8), CompareWord8);
            break;
        case TYPE_UWord8:
            qsort(data, numOfElements, sizeof(WebRtc_UWord8), CompareUWord8);
            break;
        case TYPE_Word16:
            qsort(data, numOfElements, sizeof(WebRtc_Word16), CompareWord16);
            break;
        case TYPE_UWord16:
            qsort(data, numOfElements, sizeof(WebRtc_UWord16), CompareUWord16);
            break;
        case TYPE_Word32:
            qsort(data, numOfElements, sizeof(WebRtc_Word32), CompareWord32);
            break;
        case TYPE_UWord32:
            qsort(data, numOfElements, sizeof(WebRtc_UWord32), CompareUWord32);
            break;
        case TYPE_Word64:
            qsort(data, numOfElements, sizeof(WebRtc_Word64), CompareWord64);
            break;
        case TYPE_UWord64:
            qsort(data, numOfElements, sizeof(WebRtc_UWord64), CompareUWord64);
            break;
        case TYPE_Float32:
            qsort(data, numOfElements, sizeof(float), CompareFloat32);
            break;
        case TYPE_Float64:
            qsort(data, numOfElements, sizeof(double), CompareFloat64);
            break;
        default:
            return -1;
        }
#else
        // Fall back to std::sort for 64-bit types and floats due to compiler
	// warnings and VS 2003 build crashes respectively with spreadsort.
        switch (type)
        {
        case TYPE_Word8:
            IntegerSort<WebRtc_Word8>(data, numOfElements);
            break;
        case TYPE_UWord8:
            IntegerSort<WebRtc_UWord8>(data, numOfElements);
            break;
        case TYPE_Word16:
            IntegerSort<WebRtc_Word16>(data, numOfElements);
            break;
        case TYPE_UWord16:
            IntegerSort<WebRtc_UWord16>(data, numOfElements);
            break;
        case TYPE_Word32:
            IntegerSort<WebRtc_Word32>(data, numOfElements);
            break;
        case TYPE_UWord32:
            IntegerSort<WebRtc_UWord32>(data, numOfElements);
            break;
        case TYPE_Word64:
            StdSort<WebRtc_Word64>(data, numOfElements);
            break;
        case TYPE_UWord64:
            StdSort<WebRtc_UWord64>(data, numOfElements);
            break;
        case TYPE_Float32:
            StdSort<float>(data, numOfElements);
            break;
        case TYPE_Float64:
            StdSort<double>(data, numOfElements);
            break;
        default:
            return -1;
        }
#endif
        return 0;
    }

    WebRtc_Word32 KeySort(void* data, void* key, WebRtc_UWord32 numOfElements,
                          WebRtc_UWord32 sizeOfElement, Type keyType)
    {
        if (data == NULL)
        {
            return -1;
        }

        if (key == NULL)
        {
            return -1;
        }

        if ((WebRtc_UWord64)numOfElements * sizeOfElement > 0xffffffff)
        {
            return -1;
        }

#ifdef NO_STL
        SortKey* ptrSortKey = new(std::nothrow) SortKey[numOfElements];
        if (ptrSortKey == NULL)
        {
            return -1;
        }

        switch (keyType)
        {
        case TYPE_Word8:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word8,
                CompareKeyWord8);
            break;
        case TYPE_UWord8:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord8,
                CompareKeyUWord8);
            break;
        case TYPE_Word16:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word16,
                CompareKeyWord16);
            break;
        case TYPE_UWord16:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord16,
                CompareKeyUWord16);
            break;
        case TYPE_Word32:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word32,
                CompareKeyWord32);
            break;
        case TYPE_UWord32:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord32,
                CompareKeyUWord32);
            break;
        case TYPE_Word64:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_Word64,
                CompareKeyWord64);
            break;
        case TYPE_UWord64:
            KEY_QSORT(ptrSortKey, key, numOfElements, WebRtc_UWord64,
                CompareKeyUWord64);
            break;
        case TYPE_Float32:
            KEY_QSORT(ptrSortKey, key, numOfElements, float,
                CompareKeyFloat32);
            break;
        case TYPE_Float64:
            KEY_QSORT(ptrSortKey, key, numOfElements, double,
                CompareKeyFloat64);
            break;
        default:
            return -1;
        }

        // Shuffle into sorted position based on index map.
        WebRtc_UWord8* ptrData = static_cast<WebRtc_UWord8*>(data);
        WebRtc_UWord8* ptrDataSorted = new(std::nothrow) WebRtc_UWord8
            [numOfElements * sizeOfElement];
        if (ptrDataSorted == NULL)
        {
            return -1;
        }

        for (WebRtc_UWord32 i = 0; i < numOfElements; i++)
        {
            memcpy(ptrDataSorted + i * sizeOfElement, ptrData +
                ptrSortKey[i].index * sizeOfElement, sizeOfElement);
        }
        memcpy(ptrData, ptrDataSorted, numOfElements * sizeOfElement);

        delete[] ptrSortKey;
        delete[] ptrDataSorted;

        return 0;
#else
        // Fall back to std::sort for 64-bit types and floats due to compiler
	// warnings and errors respectively with spreadsort.
        switch (keyType)
        {
        case TYPE_Word8:
            return IntegerKeySort<WebRtc_Word8>(data, key, numOfElements,
                                                sizeOfElement);
        case TYPE_UWord8:
            return IntegerKeySort<WebRtc_UWord8>(data, key, numOfElements,
                                                 sizeOfElement);
        case TYPE_Word16:
            return IntegerKeySort<WebRtc_Word16>(data, key, numOfElements,
                                                 sizeOfElement);
        case TYPE_UWord16:
            return IntegerKeySort<WebRtc_UWord16>(data, key, numOfElements,
                                                  sizeOfElement);
        case TYPE_Word32:
            return IntegerKeySort<WebRtc_Word32>(data, key, numOfElements,
                                                 sizeOfElement);
        case TYPE_UWord32:
            return IntegerKeySort<WebRtc_UWord32>(data, key, numOfElements,
                                                  sizeOfElement);
        case TYPE_Word64:
            return StdKeySort<WebRtc_Word64>(data, key, numOfElements,
                                             sizeOfElement);
        case TYPE_UWord64:
            return StdKeySort<WebRtc_UWord64>(data, key, numOfElements,
                                              sizeOfElement);
        case TYPE_Float32:
            return StdKeySort<float>(data, key, numOfElements, sizeOfElement);
        case TYPE_Float64:
            return StdKeySort<double>(data, key, numOfElements, sizeOfElement);
        default:
            return -1;
        }
#endif
    }
} // namespace webrtc
