// © 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:   UTF-8
*   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(void) {
    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) {
    (void)lines; // suppress compiler warnings about unused variable
#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(void) {
    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
}
