// Copyright (C) 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
*******************************************************************************
*
*   Copyright (C) 2003-2014, International Business Machines
*   Corporation and others.  All Rights Reserved.
*
*******************************************************************************
*   file name:  sorttest.c
*   encoding:   US-ASCII
*   tab size:   8 (not used)
*   indentation:4
*
*   created on: 2003aug04
*   created by: Markus W. Scherer
*
*   Test internal sorting functions.
*/

#include <stdio.h>

#include "unicode/utypes.h"
#include "unicode/ucol.h"
#include "unicode/ustring.h"
#include "cmemory.h"
#include "cintltst.h"
#include "uarrsort.h"

static void
SortTest() {
    uint16_t small[]={ 8, 1, 2, 5, 4, 3, 7, 6 };
    int32_t medium[]={ 10, 8, 1, 2, 5, 5, -1, 6, 4, 3, 9, 7, 5 };
    uint32_t large[]={ 21, 10, 20, 19, 11, 12, 13, 10, 10, 10, 10,
                       8, 1, 2, 5, 10, 10, 4, 17, 18, 3, 9, 10, 7, 6, 14, 15, 16 };

    int32_t i;
    UErrorCode errorCode;

    /* sort small array (stable) */
    errorCode=U_ZERO_ERROR;
    uprv_sortArray(small, UPRV_LENGTHOF(small), sizeof(small[0]), uprv_uint16Comparator, NULL, TRUE, &errorCode);
    if(U_FAILURE(errorCode)) {
        log_err("uprv_sortArray(small) failed - %s\n", u_errorName(errorCode));
        return;
    }
    for(i=1; i<UPRV_LENGTHOF(small); ++i) {
        if(small[i-1]>small[i]) {
            log_err("uprv_sortArray(small) mis-sorted [%d]=%u > [%d]=%u\n", i-1, small[i-1], i, small[i]);
            return;
        }
    }

    /* for medium, add bits that will not be compared, to test stability */
    for(i=0; i<UPRV_LENGTHOF(medium); ++i) {
        medium[i]=(int32_t)((uint32_t)medium[i]<<4) | i;
    }

    /* sort medium array (stable) */
    uprv_sortArray(medium, UPRV_LENGTHOF(medium), sizeof(medium[0]), uprv_int32Comparator, NULL, TRUE, &errorCode);
    if(U_FAILURE(errorCode)) {
        log_err("uprv_sortArray(medium) failed - %s\n", u_errorName(errorCode));
        return;
    }
    for(i=1; i<UPRV_LENGTHOF(medium); ++i) {
        if(medium[i-1]>=medium[i]) {
            log_err("uprv_sortArray(medium) mis-sorted [%d]=%u > [%d]=%u\n", i-1, medium[i-1], i, medium[i]);
            return;
        }
    }

    /* sort large array (not stable) */
    errorCode=U_ZERO_ERROR;
    uprv_sortArray(large, UPRV_LENGTHOF(large), sizeof(large[0]), uprv_uint32Comparator, NULL, FALSE, &errorCode);
    if(U_FAILURE(errorCode)) {
        log_err("uprv_sortArray(large) failed - %s\n", u_errorName(errorCode));
        return;
    }
    for(i=1; i<UPRV_LENGTHOF(large); ++i) {
        if(large[i-1]>large[i]) {
            log_err("uprv_sortArray(large) mis-sorted [%d]=%u > [%d]=%u\n", i-1, large[i-1], i, large[i]);
            return;
        }
    }
}

#if !UCONFIG_NO_COLLATION

/*
 * Fill an array with semi-random short strings.
 * Vary them enough to be interesting, but create duplicates.
 * With CYCLE=10 characters per STR_LEN=3 string positions there are only 1000 unique strings.
 * NUM_LINES should be larger than this.
 */
#define NUM_LINES 10000
#define STR_LEN 3
#define CYCLE 10

/*
 * Use characters beyond the Latin Extended A block to avoid a collator fastpath.
 * They should sort unique, so that we can later use a binary comparison for string equality.
 */
#define BASE_CHAR 0x200

typedef struct Line {
    UChar s[STR_LEN];
    int32_t recordNumber;
} Line;

static void
printLines(const Line *lines) {
#if 0
    int32_t i, j;
    for(i=0; i<NUM_LINES; ++i) {
        const Line *line=lines+i;
        for(j=0; j<STR_LEN; ++j) {
            printf("%04x ", line->s[j]);
        }
        printf(" #%5d\n", line->recordNumber);
    }
#endif
}

/* Use a collator so that the comparisons are not essentially free, for simple benchmarking. */
static int32_t U_EXPORT2
linesComparator(const void *context, const void *left, const void *right) {
    const UCollator *coll=(const UCollator *)context;
    const Line *leftLine=(const Line *)left;
    const Line *rightLine=(const Line *)right;
    /* compare the strings but not the record number */
    return ucol_strcoll(coll, leftLine->s, STR_LEN, rightLine->s, STR_LEN);
}

static void StableSortTest() {
    UErrorCode errorCode=U_ZERO_ERROR;
    UCollator *coll;
    Line *lines, *p;
    UChar s[STR_LEN];
    int32_t i, j;

    coll=ucol_open("root", &errorCode);
    if(U_FAILURE(errorCode)) {
        log_data_err("ucol_open(root) failed - %s\n", u_errorName(errorCode));
        return;
    }

    lines=p=(Line *)uprv_malloc(NUM_LINES*sizeof(Line));
    uprv_memset(lines, 0, NUM_LINES*sizeof(Line));  /* avoid uninitialized memory */

    for(j=0; j<STR_LEN; ++j) { s[j]=BASE_CHAR; }
    j=0;
    for(i=0; i<NUM_LINES; ++i) {
        UChar c;
        u_memcpy(p->s, s, STR_LEN);
        p->recordNumber=i;
        /* Modify the string for the next line. */
        c=s[j]+1;
        if(c==BASE_CHAR+CYCLE) { c=BASE_CHAR; }
        s[j]=c;
        if(++j==STR_LEN) { j=0; }
        ++p;
    }
    puts("\n* lines before sorting");
    printLines(lines);

    uprv_sortArray(lines, NUM_LINES, (int32_t)sizeof(Line),
                   linesComparator, coll, TRUE, &errorCode);
    if(U_FAILURE(errorCode)) {
        log_err("uprv_sortArray() failed - %s\n", u_errorName(errorCode));
        return;
    }
    puts("* lines after sorting");
    printLines(lines);

    /* Verify that the array is sorted correctly. */
    p=lines;
    for(i=1; i<NUM_LINES; ++i) {
        Line *q=p+1;  /* =lines+i */
        /* Binary comparison first, for speed. In this case, equal strings must be identical. */
        int32_t diff=u_strCompare(p->s, STR_LEN, q->s, STR_LEN, FALSE);
        if(diff==0) {
            if(p->recordNumber>=q->recordNumber) {
                log_err("equal strings %d and %d out of order at sorted index %d\n",
                        (int)p->recordNumber, (int)q->recordNumber, (int)i);
                break;
            }
        } else {
            /* Compare unequal strings with the collator. */
            diff=ucol_strcoll(coll, p->s, STR_LEN, q->s, STR_LEN);
            if(diff>=0) {
                log_err("unequal strings %d and %d out of order at sorted index %d\n",
                        (int)p->recordNumber, (int)q->recordNumber, (int)i);
                break;
            }
        }
        p=q;
    }

    uprv_free(lines);
    ucol_close(coll);
}

#endif  /* !UCONFIG_NO_COLLATION */

void
addSortTest(TestNode** root);

void
addSortTest(TestNode** root) {
    addTest(root, &SortTest, "tsutil/sorttest/SortTest");
#if !UCONFIG_NO_COLLATION
    addTest(root, &StableSortTest, "tsutil/sorttest/StableSortTest");
#endif
}
