/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package benchmarks.regression;

import java.util.Locale;
import com.google.caliper.Param;
import com.google.caliper.SimpleBenchmark;

public class StringCaseMappingBenchmark extends SimpleBenchmark {
    enum Inputs {
        EMPTY(""),

        // TODO: include hairy inputs like turkish and greek.
        // TODO: locale makes a difference too.

        LOWER2(lower(2)),
        UPPER2(upper(2)),
        MIXED2(mixed(2)),

        LOWER8(lower(8)),
        UPPER8(upper(8)),
        MIXED8(mixed(8)),

        LOWER32(lower(32)),
        UPPER32(upper(32)),
        MIXED32(mixed(32)),

        LOWER512(lower(512)),
        UPPER512(upper(512)),
        MIXED512(mixed(512)),

        LOWER2048(lower(2048)),
        UPPER2048(upper(2048)),
        MIXED2048(mixed(2048)),

        LOWER_1M(lower(1024*1024)),
        UPPER_1M(upper(1024*1024)),
        MIXED_1M(mixed(1024*1024));

        final String value;
        private Inputs(String value) { this.value = value; }
        private static String lower(int length) {
            return makeString(length, "a0b1c2d3e4f5g6h7i8j9klmnopqrstuvwxyz");
        }
        private static String upper(int length) {
            return makeString(length, "A0B1C2D3E4F5G6H7I8J9KLMNOPQRSTUVWXYZ");
        }
        private static String mixed(int length) {
            return makeString(length, "Aa0Bb1Cc2Dd3Ee4Ff5Gg6Hh7Ii8Jj9KkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
        }
        private static String makeString(int length, String alphabet) {
            StringBuilder sb = new StringBuilder(length);
            for (int i = 0; i < length; ++i) {
                sb.append(alphabet.charAt(i % alphabet.length()));
            }
            return sb.toString();
        }
    }
    @Param private Inputs s;

    public void timeToUpperCase_US(int reps) {
        for (int i = 0; i < reps; ++i) {
            s.value.toUpperCase(Locale.US);
        }
    }

    public void timeToLowerCase_US(int reps) {
        for (int i = 0; i < reps; ++i) {
            s.value.toUpperCase(Locale.US);
        }
    }

    public void timeToUpperCase_Ascii(int reps) {
        for (int i = 0; i < reps; ++i) {
            toUpperCaseAscii(s.value);
        }
    }

    public void timeToLowerCase_Ascii(int reps) {
        for (int i = 0; i < reps; ++i) {
            toUpperCaseAscii(s.value);
        }
    }

    public void timeToUpperCase_ICU(int reps) {
        for (int i = 0; i < reps; ++i) {
            libcore.icu.ICU.toUpperCase(s.value, Locale.US.toString());
        }
    }

    public void timeToLowerCase_ICU(int reps) {
        for (int i = 0; i < reps; ++i) {
            libcore.icu.ICU.toLowerCase(s.value, Locale.US.toString());
        }
    }

    public static String toUpperCaseAscii(String s) {
        for (int i = 0, length = s.length(); i < length; i++) {
            char c = s.charAt(i);
            if (c < 'a' || c > 'z') {
                continue; // fast path avoids allocation
            }

            // slow path: s contains lower case chars
            char[] result = s.toCharArray();
            for (; i < length; i++) {
                c = result[i];
                if (c >= 'a' && c <= 'z') {
                    result[i] -= ('a' - 'A');
                }
            }
            return new String(result);
        }
        return s;
    }

    public static String toLowerCaseAscii(String s) {
        for (int i = 0, length = s.length(); i < length; i++) {
            char c = s.charAt(i);
            if (c < 'A' || c > 'Z') {
                continue; // fast path avoids allocation
            }

            // slow path: s contains upper case chars
            char[] result = s.toCharArray();
            for (; i < length; i++) {
                c = result[i];
                if (c >= 'A' && c <= 'Z') {
                    result[i] += ('a' - 'A');
                }
            }
            return new String(result);
        }
        return s;
    }
}
