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

// Old implementation for phone_number_compare(), which has used in cupcake, but once replaced with
// the new, more strict version, and reverted again.

#include <string.h>

namespace android {

static int MIN_MATCH = 7;

/** True if c is ISO-LATIN characters 0-9 */
static bool isISODigit (char c)
{
    return c >= '0' && c <= '9';
}

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

/**
 * Phone numbers are stored in "lookup" form in the database
 * as reversed strings to allow for caller ID lookup
 *
 * This method takes a phone number and makes a valid SQL "LIKE"
 * string that will match the lookup form
 *
 */
/** all of a up to len must be an international prefix or
 *  separators/non-dialing digits
 */
static bool matchIntlPrefix(const char* a, int len)
{
    /* '([^0-9*#+]\+[^0-9*#+] | [^0-9*#+]0(0|11)[^0-9*#+] )$' */
    /*        0    1                     2 3 45               */

    int state = 0;
    for (int i = 0 ; i < len ; i++) {
        char c = a[i];

        switch (state) {
            case 0:
                if      (c == '+') state = 1;
                else if (c == '0') state = 2;
                else if (isNonSeparator(c)) return false;
            break;

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

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

            default:
                if (isNonSeparator(c)) return false;
            break;

        }
    }

    return state == 1 || state == 3 || state == 5;
}

/** all of 'a' up to len must match non-US trunk prefix ('0') */
static bool matchTrunkPrefix(const char* a, int len)
{
    bool found;

    found = false;

    for (int i = 0 ; i < len ; i++) {
        char c = a[i];

        if (c == '0' && !found) {
            found = true;
        } else if (isNonSeparator(c)) {
            return false;
        }
    }

    return found;
}

/** all of 'a' up to len must be a (+|00|011)country code)
 *  We're fast and loose with the country code. Any \d{1,3} matches */
static bool matchIntlPrefixAndCC(const char* a, int len)
{
    /*  [^0-9*#+]*(\+|0(0|11)\d\d?\d? [^0-9*#+] $ */
    /*      0       1 2 3 45  6 7  8              */

    int state = 0;
    for (int i = 0 ; i < len ; i++ ) {
        char c = a[i];

        switch (state) {
            case 0:
                if      (c == '+') state = 1;
                else if (c == '0') state = 2;
                else if (isNonSeparator(c)) return false;
            break;

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

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

            case 1:
            case 3:
            case 5:
                if      (isISODigit(c)) state = 6;
                else if (isNonSeparator(c)) return false;
            break;

            case 6:
            case 7:
                if      (isISODigit(c)) state++;
                else if (isNonSeparator(c)) return false;
            break;

            default:
                if (isNonSeparator(c)) return false;
        }
    }

    return state == 6 || state == 7 || state == 8;
}

/**
 * Compare phone numbers a and b, return true if they're identical
 * enough for caller ID purposes.
 *
 * - Compares from right to left
 * - requires minimum characters to match
 * - handles common trunk prefixes and international prefixes
 *   (basically, everything except the Russian trunk prefix)
 *
 * Tolerates nulls
 */
bool phone_number_compare_loose_with_minmatch(const char* a, const char* b, int min_match)
{
    int ia, ib;
    int matched;
    int numSeparatorCharsInA = 0;
    int numSeparatorCharsInB = 0;

    if (a == NULL || b == NULL) {
        return false;
    }

    ia = strlen(a);
    ib = strlen(b);
    if (ia == 0 || ib == 0) {
        return false;
    }

    // Compare from right to left
    ia--;
    ib--;

    matched = 0;

    while (ia >= 0 && ib >=0) {
        char ca, cb;
        bool skipCmp = false;

        ca = a[ia];

        if (!isNonSeparator(ca)) {
            ia--;
            skipCmp = true;
            numSeparatorCharsInA++;
        }

        cb = b[ib];

        if (!isNonSeparator(cb)) {
            ib--;
            skipCmp = true;
            numSeparatorCharsInB++;
        }

        if (!skipCmp) {
            if (cb != ca) {
                break;
            }
            ia--; ib--; matched++;
        }
    }

    if (matched < min_match) {
        const int effectiveALen = strlen(a) - numSeparatorCharsInA;
        const int effectiveBLen = strlen(b) - numSeparatorCharsInB;

        // if the number of dialable chars in a and b match, but the matched chars < min_match,
        // treat them as equal (i.e. 404-04 and 40404)
        if (effectiveALen == effectiveBLen && effectiveALen == matched) {
            return true;
        }

        return false;
    }

    // At least one string has matched completely;
    if (matched >= min_match && (ia < 0 || ib < 0)) {
        return true;
    }

    /*
     * Now, what remains must be one of the following for a
     * match:
     *
     *  - a '+' on one and a '00' or a '011' on the other
     *  - a '0' on one and a (+,00)<country code> on the other
     *     (for this, a '0' and a '00' prefix would have succeeded above)
     */

    if (matchIntlPrefix(a, ia + 1) && matchIntlPrefix(b, ib + 1)) {
        return true;
    }

    if (matchTrunkPrefix(a, ia + 1) && matchIntlPrefixAndCC(b, ib + 1)) {
        return true;
    }

    if (matchTrunkPrefix(b, ib + 1) && matchIntlPrefixAndCC(a, ia + 1)) {
        return true;
    }

    /*
     * Last resort: if the number of unmatched characters on both sides is less than or equal
     * to the length of the longest country code and only one number starts with a + accept
     * the match. This is because some countries like France and Russia have an extra prefix
     * digit that is used when dialing locally in country that does not show up when you dial
     * the number using the country code. In France this prefix digit is used to determine
     * which land line carrier to route the call over.
     */
    bool aPlusFirst = (*a == '+');
    bool bPlusFirst = (*b == '+');
    bool aIgnoreUnmatched = aPlusFirst && (ia - ib) >= 0 && (ia - ib) <= 1;
    bool bIgnoreUnmatched = bPlusFirst && (ib - ia) >= 0 && (ib - ia) <= 1;
    if (ia < 4 && ib < 4 && (aIgnoreUnmatched || bIgnoreUnmatched) && !(aPlusFirst && bPlusFirst)) {
        return true;
    }

    return false;
}

bool phone_number_compare_loose(const char* a, const char* b)
{
    return phone_number_compare_loose_with_minmatch(a, b, MIN_MATCH);
}

}  // namespace android
