/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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 com.android.tools.lint.checks;

import static com.android.tools.lint.checks.PluralsDatabase.Quantity.few;
import static com.android.tools.lint.checks.PluralsDatabase.Quantity.many;
import static com.android.tools.lint.checks.PluralsDatabase.Quantity.one;
import static com.android.tools.lint.checks.PluralsDatabase.Quantity.two;
import static com.android.tools.lint.checks.PluralsDatabase.Quantity.zero;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.tools.lint.detector.api.LintUtils;
import com.google.common.collect.Maps;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;

/**
 * Database used by the {@link com.android.tools.lint.checks.PluralsDetector} to get information
 * about plural forms for a given language
 */
public class PluralsDatabase {
    private static final EnumSet<Quantity> NONE = EnumSet.noneOf(Quantity.class);

    private static final PluralsDatabase sInstance = new PluralsDatabase();
    private Map<String, EnumSet<Quantity>> mPlurals = Maps.newHashMap();

    /** Bit set if this language uses quantity zero */
    @SuppressWarnings("PointlessBitwiseExpression")
    static final int FLAG_ZERO  = 1 << 0;
    /** Bit set if this language uses quantity one */
    static final int FLAG_ONE   = 1 << 1;
    /** Bit set if this language uses quantity two */
    static final int FLAG_TWO   = 1 << 2;
    /** Bit set if this language uses quantity few */
    static final int FLAG_FEW   = 1 << 3;
    /** Bit set if this language uses quantity many */
    static final int FLAG_MANY  = 1 << 4;
    /** Bit set if this language has multiple values that match quantity zero */
    static final int FLAG_MULTIPLE_ZERO = 1 << 5;
    /** Bit set if this language has multiple values that match quantity one */
    static final int FLAG_MULTIPLE_ONE  = 1 << 6;
    /** Bit set if this language has multiple values that match quantity two */
    static final int FLAG_MULTIPLE_TWO  = 1 << 7;

    @NonNull
    public static PluralsDatabase get() {
        return sInstance;
    }

    private static int getFlags(@NonNull String language) {
        int index = getLanguageIndex(language);
        if (index != -1) {
            return FLAGS[index];
        }
        return 0;
    }

    private static int getLanguageIndex(@NonNull String language) {
        int index = Arrays.binarySearch(LANGUAGE_CODES, language);
        if (index >= 0) {
            assert LANGUAGE_CODES[index].equals(language);
            return index;
        } else {
            return -1;
        }
    }

    @Nullable
    public EnumSet<Quantity> getRelevant(@NonNull String language) {
        EnumSet<Quantity> set = mPlurals.get(language);
        if (set == null) {
            int index = getLanguageIndex(language);
            if (index == -1) {
                mPlurals.put(language, NONE);
                return null;
            }

            // Process each item and look for relevance
            int flag = FLAGS[index];

            set = EnumSet.noneOf(Quantity.class);
            if ((flag & FLAG_ZERO) != 0) {
                set.add(zero);
            }
            if ((flag & FLAG_ONE) != 0) {
                set.add(one);
            }
            if ((flag & FLAG_TWO) != 0) {
                set.add(two);
            }
            if ((flag & FLAG_FEW) != 0) {
                set.add(few);
            }
            if ((flag & FLAG_MANY) != 0) {
                set.add(many);
            }

            mPlurals.put(language, set);
        }
        return set == NONE ? null : set;
    }

    @SuppressWarnings("MethodMayBeStatic")
    public boolean hasMultipleValuesForQuantity(
            @NonNull String language,
            @NonNull Quantity quantity) {
        if (quantity == one) {
            return (getFlags(language) & FLAG_MULTIPLE_ONE) != 0;
        } else if (quantity == two) {
            return (getFlags(language) & FLAG_MULTIPLE_TWO) != 0;
        } else {
            return quantity == zero && (getFlags(language) & FLAG_MULTIPLE_ZERO) != 0;
        }
    }

    @SuppressWarnings("MethodMayBeStatic")
    @Nullable
    public String findIntegerExamples(@NonNull String language, @NonNull Quantity quantity) {
        if (quantity == one) {
            return getExampleForQuantityOne(language);
        } else if (quantity == two) {
            return getExampleForQuantityTwo(language);
        } else if (quantity == zero) {
            return getExampleForQuantityZero(language);
        } else {
            return null;
        }
    }

    public enum Quantity {
        // deliberately lower case to match attribute names
        few, many, one, two, zero, other;

        @Nullable
        public static Quantity get(@NonNull String name) {
            for (Quantity quantity : values()) {
                if (name.equals(quantity.name())) {
                    return quantity;
                }
            }

            return null;
        }

        public static String formatSet(@NonNull EnumSet<Quantity> set) {
            List<String> list = new ArrayList<String>(set.size());
            for (Quantity quantity : set) {
                list.add('`' + quantity.name() + '`');
            }
            return LintUtils.formatList(list, Integer.MAX_VALUE);
        }
    }

    // GENERATED DATA.
    // This data is generated by the #testDatabaseAccurate method in PluralsDatabaseTest
    // which will generate the following if it can find an ICU plurals database file
    // in the unit test data folder.

    /** Set of language codes relevant to plurals data */
    private static final String[] LANGUAGE_CODES = new String[] {
            "af", "ak", "am", "ar", "az", "be", "bg", "bh", "bm", "bn",
            "bo", "br", "bs", "ca", "cs", "cy", "da", "de", "dv", "dz",
            "ee", "el", "en", "eo", "es", "et", "eu", "fa", "ff", "fi",
            "fo", "fr", "fy", "ga", "gd", "gl", "gu", "gv", "ha", "he",
            "hi", "hr", "hu", "hy", "id", "ig", "ii", "in", "is", "it",
            "iu", "iw", "ja", "ji", "jv", "ka", "kk", "kl", "km", "kn",
            "ko", "ks", "ku", "kw", "ky", "lb", "lg", "ln", "lo", "lt",
            "lv", "mg", "mk", "ml", "mn", "mr", "ms", "mt", "my", "nb",
            "nd", "ne", "nl", "nn", "no", "nr", "ny", "om", "or", "os",
            "pa", "pl", "ps", "pt", "rm", "ro", "ru", "se", "sg", "si",
            "sk", "sl", "sn", "so", "sq", "sr", "ss", "st", "sv", "sw",
            "ta", "te", "th", "ti", "tk", "tl", "tn", "to", "tr", "ts",
            "ug", "uk", "ur", "uz", "ve", "vi", "vo", "wa", "wo", "xh",
            "yi", "yo", "zh", "zu"
    };

    /**
     * Relevant flags for each language (corresponding to each language listed
     * in the same position in {@link #LANGUAGE_CODES}).
     */
    private static final int[] FLAGS = new int[] {
            0x0002, 0x0042, 0x0042, 0x001f, 0x0002, 0x005a, 0x0002, 0x0042,
            0x0000, 0x0042, 0x0000, 0x00de, 0x004a, 0x0002, 0x000a, 0x001f,
            0x0002, 0x0002, 0x0002, 0x0000, 0x0002, 0x0002, 0x0002, 0x0002,
            0x0002, 0x0002, 0x0002, 0x0042, 0x0042, 0x0002, 0x0002, 0x0042,
            0x0002, 0x001e, 0x00ce, 0x0002, 0x0042, 0x00ce, 0x0002, 0x0016,
            0x0042, 0x004a, 0x0002, 0x0042, 0x0000, 0x0000, 0x0000, 0x0000,
            0x0042, 0x0002, 0x0006, 0x0016, 0x0000, 0x0002, 0x0000, 0x0002,
            0x0002, 0x0002, 0x0000, 0x0042, 0x0000, 0x0002, 0x0002, 0x0006,
            0x0002, 0x0002, 0x0002, 0x0042, 0x0000, 0x004a, 0x0063, 0x0042,
            0x0042, 0x0002, 0x0002, 0x0042, 0x0000, 0x001a, 0x0000, 0x0002,
            0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
            0x0002, 0x0002, 0x0042, 0x001a, 0x0002, 0x0002, 0x0002, 0x000a,
            0x005a, 0x0006, 0x0000, 0x0042, 0x000a, 0x00ce, 0x0002, 0x0002,
            0x0002, 0x004a, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
            0x0000, 0x0042, 0x0002, 0x0042, 0x0002, 0x0000, 0x0002, 0x0002,
            0x0002, 0x005a, 0x0002, 0x0002, 0x0002, 0x0000, 0x0002, 0x0042,
            0x0000, 0x0002, 0x0002, 0x0000, 0x0000, 0x0042
    };

    @Nullable
    private static String getExampleForQuantityZero(@NonNull String language) {
        int index = getLanguageIndex(language);
        switch (index) {
            // set14
            case 70: // lv
                return "0, 10~20, 30, 40, 50, 60, 100, 1000, 10000, 100000, 1000000, \u2026";
            case -1:
            default:
                return null;
        }
    }

    @Nullable
    private static String getExampleForQuantityOne(@NonNull String language) {
        int index = getLanguageIndex(language);
        switch (index) {
            // set1
            case 2: // am
            case 9: // bn
            case 27: // fa
            case 36: // gu
            case 40: // hi
            case 59: // kn
            case 75: // mr
            case 133: // zu
                return "0, 1";
            // set11
            case 48: // is
                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
            // set12
            case 72: // mk
                return "1, 11, 21, 31, 41, 51, 61, 71, 101, 1001, \u2026";
            // set13
            case 115: // tl
                return "0~3, 5, 7, 8, 10~13, 15, 17, 18, 20, 21, 100, 1000, 10000, 100000, 1000000, \u2026";
            // set14
            case 70: // lv
                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
            // set2
            case 28: // ff
            case 31: // fr
            case 43: // hy
                return "0, 1";
            // set20
            case 12: // bs
            case 41: // hr
            case 105: // sr
                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
            // set21
            case 34: // gd
                return "1, 11";
            // set22
            case 101: // sl
                return "1, 101, 201, 301, 401, 501, 601, 701, 1001, \u2026";
            // set26
            case 5: // be
                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
            // set27
            case 69: // lt
                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
            // set29
            case 96: // ru
            case 121: // uk
                return "1, 21, 31, 41, 51, 61, 71, 81, 101, 1001, \u2026";
            // set30
            case 11: // br
                return "1, 21, 31, 41, 51, 61, 81, 101, 1001, \u2026";
            // set32
            case 37: // gv
                return "1, 11, 21, 31, 41, 51, 61, 71, 101, 1001, \u2026";
            // set5
            case 99: // si
                return "0, 1";
            // set6
            case 1: // ak
            case 7: // bh
            case 67: // ln
            case 71: // mg
            case 90: // pa
            case 113: // ti
            case 127: // wa
                return "0, 1";
            case -1:
            default:
                return null;
        }
    }

    @Nullable
    private static String getExampleForQuantityTwo(@NonNull String language) {
        int index = getLanguageIndex(language);
        switch (index) {
            // set21
            case 34: // gd
                return "2, 12";
            // set22
            case 101: // sl
                return "2, 102, 202, 302, 402, 502, 602, 702, 1002, \u2026";
            // set30
            case 11: // br
                return "2, 22, 32, 42, 52, 62, 82, 102, 1002, \u2026";
            // set32
            case 37: // gv
                return "2, 12, 22, 32, 42, 52, 62, 72, 102, 1002, \u2026";
            case -1:
            default:
                return null;
        }
    }
}
