/*
 * Copyright 2009, 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.
 */

#include <string.h>

namespace android {

/* Generated by the following Python script. Values of country calling codes
   are from http://en.wikipedia.org/wiki/List_of_country_calling_codes

#!/usr/bin/python
import sys
ccc_set_2digits = set([0, 1, 7,
                       20, 27, 28, 30, 31, 32, 33, 34, 36, 39, 40, 43, 44, 45,
                       46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61,
                       62, 63, 64, 65, 66, 81, 82, 83, 84, 86, 89, 90, 91, 92,
                       93, 94, 95, 98])

ONE_LINE_NUM = 10

for i in xrange(100):
  if i % ONE_LINE_NUM == 0:
    sys.stdout.write('    ')
  if i in ccc_set_2digits:
    included = 'true'
  else:
    included = 'false'
  sys.stdout.write(included + ',')
  if ((i + 1) % ONE_LINE_NUM) == 0:
    sys.stdout.write('\n')
  else:
    sys.stdout.write(' ')
*/
static bool two_length_country_code_map[100] = {
    true, true, false, false, false, false, false, true, false, false,
    false, false, false, false, false, false, false, false, false, false,
    true, false, false, false, false, false, false, true, true, false,
    true, true, true, true, true, false, true, false, false, true,
    true, false, false, true, true, true, true, true, true, true,
    false, true, true, true, true, true, true, true, true, false,
    true, true, true, true, true, true, true, false, false, false,
    false, false, false, false, false, false, false, false, false, false,
    false, true, true, true, true, false, true, false, false, true,
    true, true, true, true, true, true, false, false, true, false,
};

#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))

/**
 * Returns true if "ccc_candidate" expresses (part of ) some country calling
 * code.
 * Returns false otherwise.
 */
static bool isCountryCallingCode(int ccc_candidate) {
    return ccc_candidate > 0 &&
            ccc_candidate < (int)ARRAY_SIZE(two_length_country_code_map) &&
            two_length_country_code_map[ccc_candidate];
}

/**
 * Returns interger corresponding to the input if input "ch" is
 * ISO-LATIN characters 0-9.
 * Returns -1 otherwise
 */
static int tryGetISODigit (char ch)
{
    if ('0' <= ch && ch <= '9') {
        return ch - '0';
    } else {
        return -1;
    }
}

/** True if c is ISO-LATIN characters 0-9, *, # , +  */
static bool isNonSeparator(char ch)
{
    return ('0' <= ch && ch <= '9') || ch == '*' || ch == '#' || ch == '+';
}

/**
 * Try to store the pointer to "new_ptr" which does not have trunk prefix.
 *
 * Currently this function simply ignore the first digit assuming it is
 * trunk prefix. Actually trunk prefix is different in each country.
 *
 * e.g.
 * "+79161234567" equals "89161234567" (Russian trunk digit is 8)
 * "+33123456789" equals "0123456789" (French trunk digit is 0)
 *
 */
static bool tryGetTrunkPrefixOmittedStr(const char *str, size_t len,
                                        const char **new_ptr, size_t *new_len)
{
    for (size_t i = 0 ; i < len ; i++) {
        char ch = str[i];
        if (tryGetISODigit(ch) >= 0) {
            if (new_ptr != NULL) {
                *new_ptr = str + i + 1;
            }
            if (new_len != NULL) {
                *new_len = len - (i + 1);
            }
            return true;
        } else if (isNonSeparator(ch)) {
            return false;
        }
    }

    return false;
}

/*
 * Note that this function does not strictly care the country calling code with
 * 3 length (like Morocco: +212), assuming it is enough to use the first two
 * digit to compare two phone numbers.
 */
static int tryGetCountryCallingCode(const char *str, size_t len,
                                    const char **new_ptr, size_t *new_len)
{
    // Rough regexp:
    //  ^[^0-9*#+]*((\+|0(0|11)\d\d?|166) [^0-9*#+] $
    //         0        1 2 3 45  6 7  89
    //
    // In all the states, this function ignores separator characters.
    // "166" is the special case for the call from Thailand to the US. Ugu!

    int state = 0;
    int ccc = 0;
    for (size_t i = 0 ; i < len ; i++ ) {
        char ch = str[i];
        switch (state) {
            case 0:
                if      (ch == '+') state = 1;
                else if (ch == '0') state = 2;
                else if (ch == '1') state = 8;
                else if (isNonSeparator(ch)) return -1;
            break;

            case 2:
                if      (ch == '0') state = 3;
                else if (ch == '1') state = 4;
                else if (isNonSeparator(ch)) return -1;
            break;

            case 4:
                if      (ch == '1') state = 5;
                else if (isNonSeparator(ch)) return -1;
            break;

            case 1:
            case 3:
            case 5:
            case 6:
            case 7:
                {
                    int ret = tryGetISODigit(ch);
                    if (ret > 0) {
                        ccc = ccc * 10 + ret;
                        if (ccc >= 100 || isCountryCallingCode(ccc)) {
                            if (new_ptr != NULL) {
                                *new_ptr = str + i + 1;
                            }
                            if (new_len != NULL) {
                                *new_len = len - (i + 1);
                            }
                            return ccc;
                        }
                        if (state == 1 || state == 3 || state == 5) {
                            state = 6;
                        } else {
                            state++;
                        }
                    } else if (isNonSeparator(ch)) {
                        return -1;
                    }
                }
                break;
            case 8:
                if (ch == '6') state = 9;
                else if (isNonSeparator(ch)) return -1;
                break;
            case 9:
                if (ch == '6') {
                    if (new_ptr != NULL) {
                        *new_ptr = str + i + 1;
                    }
                    if (new_len != NULL) {
                        *new_len = len - (i + 1);
                    }
                    return 66;
                } else {
                    return -1;
                }
                break;
            default:
                return -1;
        }
    }

    return -1;
}

/**
 * Return true if the prefix of "ch" is "ignorable". Here, "ignorable" means
 * that "ch" has only one digit and separater characters. The one digit is
 * assumed to be trunk prefix.
 */
static bool checkPrefixIsIgnorable(const char* ch, int i) {
    bool trunk_prefix_was_read = false;
    while (i >= 0) {
        if (tryGetISODigit(ch[i]) >= 0) {
            if (trunk_prefix_was_read) {
                // More than one digit appeared, meaning that "a" and "b"
                // is different.
                return false;
            } else {
                // Ignore just one digit, assuming it is trunk prefix.
                trunk_prefix_was_read = true;
            }
        } else if (isNonSeparator(ch[i])) {
            // Trunk prefix is a digit, not "*", "#"...
            return false;
        }
        i--;
    }

    return true;
}

/**
 * Compare phone numbers a and b, return true if they're identical
 * enough for caller ID purposes.
 *
 * Assume NULL as 0-length string.
 *
 * Detailed information:
 * Currently (as of 2009-06-12), we cannot depend on the locale given from the
 * OS. For example, current Android does not accept "en_JP", meaning
 * "the display language is English but the phone should be in Japan", but
 * en_US, es_US, etc. So we cannot identify which digit is valid trunk prefix
 * in the country where the phone is used. More specifically, "880-1234-1234"
 * is not valid phone number in Japan since the trunk prefix in Japan is not 8
 * but 0 (correct number should be "080-1234-1234"), while Russian trunk prefix
 * is 8. Also, we cannot know whether the country where users live has trunk
 * prefix itself. So, we cannot determine whether "+81-80-1234-1234" is NOT
 * same as "880-1234-1234" (while "+81-80-1234-1234" is same as "080-1234-1234"
 * and we can determine "880-1234-1234" is different from "080-1234-1234").
 *
 * In the future, we should handle trunk prefix more correctly, but as of now,
 * we just ignore it...
 */
bool phone_number_compare(const char* a, const char* b)
{
    size_t len_a = 0;
    size_t len_b = 0;
    if (a == NULL) {
        a = "";
    } else {
        len_a = strlen(a);
    }
    if (b == NULL) {
        b = "";
    } else {
        len_b = strlen(b);
    }

    const char* tmp_a = NULL;
    const char* tmp_b = NULL;
    size_t tmp_len_a = len_a;
    size_t tmp_len_b = len_b;

    int ccc_a = tryGetCountryCallingCode(a, len_a, &tmp_a, &tmp_len_a);
    int ccc_b = tryGetCountryCallingCode(b, len_b, &tmp_b, &tmp_len_b);
    bool ok_to_ignore_prefix = true;
    if (ccc_a >= 0 && ccc_b >= 0) {
        if (ccc_a != ccc_b) {
            // Different Country Calling Code. Must be different phone number.
            return false;
        }
        // When both have ccc, do not ignore trunk prefix. Without this,
        // "+81123123" becomes same as "+810123123" (+81 == Japan)
        ok_to_ignore_prefix = false;
    } else if (ccc_a < 0 && ccc_b < 0) {
        // When both do not have ccc, do not ignore trunk prefix. Without this,
        // "123123" becomes same as "0123123"
        ok_to_ignore_prefix = false;
    } else {
        if (ccc_a < 0) {
            tryGetTrunkPrefixOmittedStr(a, len_a, &tmp_a, &tmp_len_a);
        }
        if (ccc_b < 0) {
            tryGetTrunkPrefixOmittedStr(b, len_b, &tmp_b, &tmp_len_b);
        }
    }

    if (tmp_a != NULL) {
        a = tmp_a;
        len_a = tmp_len_a;
    }
    if (tmp_b != NULL) {
        b = tmp_b;
        len_b = tmp_len_b;
    }

    int i_a = len_a - 1;
    int i_b = len_b - 1;
    while (i_a >= 0 && i_b >= 0) {
        bool skip_compare = false;
        char ch_a = a[i_a];
        char ch_b = b[i_b];
        if (!isNonSeparator(ch_a)) {
            i_a--;
            skip_compare = true;
        }
        if (!isNonSeparator(ch_b)) {
            i_b--;
            skip_compare = true;
        }

        if (!skip_compare) {
            if (ch_a != ch_b) {
                return false;
            }
            i_a--;
            i_b--;
        }
    }

    if (ok_to_ignore_prefix) {
        if (!checkPrefixIsIgnorable(a, i_a)) {
            return false;
        }
        if (!checkPrefixIsIgnorable(b, i_b)) {
            return false;
        }
    } else {
        // In the US, 1-650-555-1234 must be equal to 650-555-1234,
        // while 090-1234-1234 must not be equalt to 90-1234-1234 in Japan.
        // This request exists just in US (with 1 trunk (NDD) prefix).
        //
        // At least, in this "rough" comparison, we should ignore the prefix
        // '1', so if the remaining non-separator number is 0, we ignore it
        // just once.
        bool may_be_namp = true;
        while (i_a >= 0) {
            const char ch_a = a[i_a];
            if (isNonSeparator(ch_a)) {
                if (may_be_namp && tryGetISODigit(ch_a) == 1) {
                    may_be_namp = false;
                } else {
                    return false;
                }
            }
            i_a--;
        }
        while (i_b >= 0) {
            const char ch_b = b[i_b];
            if (isNonSeparator(ch_b)) {
                if (may_be_namp && tryGetISODigit(ch_b) == 1) {
                    may_be_namp = false;
                } else {
                    return false;
                }
            }
            i_b--;
        }
    }

    return true;
}

} // namespace android
