// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage

void test_strlen (string s)
{
    printf ("strlen(\"%s\") = %d\n", s, strlen(s));
}


void test_substr (string s, int begin, int len)
{
    printf ("substr(\"%s\", %d, %d) = \"%s\"\n",
            s, begin, len, substr(s,begin,len));
}


void test_substr (string s, int begin)
{
    printf ("substr(\"%s\", %d) = \"%s\"\n",
            s, begin, substr(s,begin));
}


void test_regex_match (string s, string r)
{
    printf ("regex_match (\"%s\", \"%s\") = %d\n",
            s, r, regex_match (s, r));
}



void test_regex_search (string s, string r)
{
    printf ("regex_match (\"%s\", \"%s\") = %d\n",
            s, r, regex_search (s, r));
}


void test_regex_search (string s, int results[6], string r)
{
    printf ("regex_match (\"%s\", \"%s\") = %d\n",
            s, r, regex_search (s, results, r));
    for (int i = 0;  i < arraylength(results);  ++i) {
        printf ("    results[%d] = %d\n", i, results[i]);
    }
}


void test_startswith (string s, string substr)
{
    printf ("startswith (\"%s\", \"%s\") = %d\n",
            s, substr, startswith (s, substr));
}


void test_endswith (string s, string substr)
{
    printf ("endswith (\"%s\", \"%s\") = %d\n",
            s, substr, endswith (s, substr));
}



void test_split (string s, string sep)
{
    printf ("testing split \"%s\" by \"%s\":\n", s, sep);
    string results[10];
    int r = split (s, results, sep);
    printf ("\t%d: ", r);
    for (int i = 0;  i < r;  ++i)
        printf (" \"%s\"", results[i]);
    printf ("\n");
}



shader
test (string param_newline = "\n")
{
    printf ("test string operations:\n\n");

    // test source code string concatenation:
    printf ("Testing abutting string literals: \"%s\"\n",
            "foo" "bar" "baz");

    // Test escape sequences
    string local_newline = "\n";
    printf ("\n");
    printf ("foo\\nbar\n");  // should print:  foo\bar
    printf ("blah '%s'\n", "foo\\nbar\n");  // should print: blah 'foo\bar
                                            //                    '
    printf ("blah2 '%s'\n", "foo\\\\");     // should print: blah2 'foo\\'
    if (local_newline != param_newline)
        error ("escaped strings don't match params vs locals\n");

    // Test format
    printf ("\n");
    string s = format ("P = %g", P);
    printf ("formtted string: '%s'\n", s);

    // Test concat
    printf ("\n");
    string a = "foo", b = "bar", c = "baz";
    printf ("concat(\"%s\", \"%s\", \"%s\") = \"%s\"\n",
            a, b, c, concat(a,b,c));

    // Test strlen
    printf ("\n");
    test_strlen ("");
    test_strlen ("abc");

    // Test substr
    printf ("\n");
    test_substr ("abcdefg", 0);
    test_substr ("abcdefg", 3);
    test_substr ("abcdefg", -2);
    test_substr ("abcdefg", 3, 2);
    test_substr ("abcdefg", 0, 20);
    test_substr ("abcdefg", 0, -4);

    // Test startswith/endswith
    printf ("\n");
    test_startswith ("abcdef", "abc");
    test_startswith ("abcdef", "def");
    test_startswith ("abcdef", "abcdefghi");
    test_startswith ("abcdef", "");
    test_startswith ("", "abc");
    test_startswith ("", "");
    test_endswith ("abcdef", "abc");
    test_endswith ("abcdef", "def");
    test_endswith ("abcdef", "abcdefghi");
    test_endswith ("abcdef", "ghiabcdef");
    test_endswith ("abcdef", "");
    test_endswith ("", "abc");
    test_endswith ("", "");

    // Conversion
    printf ("\n");
    string conv = "-23";
    printf ("stoi(\"%s\") = %d\n", conv, stoi(conv));
    conv = "3.14";
    printf ("stof(\"%s\") = %f\n", conv, stof(conv));

    // Split
    printf ("\n");
    test_split (" 2 4\t6    8", "");
    test_split ("3,6,9,12", ",");

    // Regular expressions
    printf ("\n");
    test_regex_match ("foo", "f");         // should not match
    test_regex_match ("foo", "f[Oo]{2}");  // should match
    test_regex_match ("foo", ".*o");       // should match
    test_regex_search ("foobar.baz", "bark");     // should not match
    test_regex_search ("foobar.baz", "bar");      // should match
    test_regex_search ("foobar.baz", "[oO]{2}");  // should match

    int results[6];
    test_regex_search ("foobar.baz", results, "(f[Oo]{2}).*(.az)");

    // ASCII Character Indexing
    printf("\n");
    a = "Hello World!";
    printf("getchar(\"%s\", 0) = %d\n", a, getchar(a, 0));
    printf("getchar(\"%s\", 11) = %d\n", a, getchar(a, 11));
    printf("getchar(\"%s\", -1) = %d\n", a, getchar(a, -1));
    printf("getchar(\"%s\", 12) = %d\n", a, getchar(a, 12));

    // String hashing
    printf("\n");
    printf("hash(\"%s\") = %d\n", a, hash(a));
    printf("hash(\"\") = %d\n", hash(""));

    // Regression test for bugs with understanding length of strings having
    // embedded escape sequences:
    printf ("strlen newline: param %d local %d literal %d\n",
            strlen(param_newline), strlen(local_newline), strlen("\n"));
}
