/*
 * 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 <ctype.h>
#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 ch is ISO-LATIN characters 0-9, *, # , +
 * Note this method current does not account for the WILD char 'N'
 */
static bool isDialable(char ch)
{
    return ('0' <= ch && ch <= '9') || ch == '*' || ch == '#' || ch == '+';
}

/** Returns true if ch is not dialable or alpha char */
static bool isSeparator(char ch)
{
    return !isDialable(ch) && (isalpha(ch) == 0);
}

/**
 * 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 (isDialable(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 (isDialable(ch)) return -1;
            break;

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

            case 4:
                if      (ch == '1') state = 5;
                else if (isDialable(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 (isDialable(ch)) {
                        return -1;
                    }
                }
                break;
            case 8:
                if (ch == '6') state = 9;
                else if (isDialable(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 (isDialable(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 (isSeparator(ch_a)) {
            i_a--;
            skip_compare = true;
        }
        if (isSeparator(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 (isDialable(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 (isDialable(ch_b)) {
                if (may_be_namp && tryGetISODigit(ch_b) == 1) {
                    may_be_namp = false;
                } else {
                    return false;
                }
            }
            i_b--;
        }
    }

    return true;
}

} // namespace android
