extension_chars = ('p', 'P', 'w', 'W', 'x', 'X')


def normalize_phone_number(number):
    common_delimiters = (',', '.', '(', ')', '-', ' ',
                         '\t', '/')
    valid_digits = ('#', '*', '0', '1', '2', '3', '4',
                    '5', '6', '7', '8', '9')

    normalized = ''

    for digit in number:
        if digit in extension_chars:
            # Keep the extension characters P, W and X,
            # but be sure they are upper case.
            digit = digit.upper()
        elif digit == '+':
            # "+" is valid only at the beginning of phone
            # numbers or after the number suppression
            # prefix. (No idea why we support only this
            # GSM code, but not the VSC ones.)
            if normalized not in ('', '*31#', '#31#'):
                print 'Wrong "+" in "%s"' % number
                # Skip this "+".
                continue
        elif digit in common_delimiters:
            # Skip this delimiter.
            continue
        elif digit in valid_digits:
            # Ok, let's keep it.
            pass
        else:
            # What is this? It doesn't seem valid but we
            # just keep it
            print 'Unknown character "%s" in "%s"' % \
                    (digit, number)

        normalized += digit

    return normalized


def remove_extension_chars(number):
    clean = ''

    for digit in number:
        if digit in extension_chars:
            # Extension character, drop this character and
            # the rest of the string.
            break

        clean += digit

    return clean


def phone_numbers_equal(number1, number2):
    number1 = normalize_phone_number(number1)
    number1 = remove_extension_chars(number1)

    number2 = normalize_phone_number(number2)
    number2 = remove_extension_chars(number2)

    # Compare only the last 7 digits.
    # If one of the numbers is shorter than 7 digits it's
    # important that the comparison is done on the full
    # length of the numbers and not only on the last tiny
    # bits of the 2 numbers.
    return number1[-7:] == number2[-7:]


if __name__ == '__main__':
    assert(normalize_phone_number('+44-82-123456789') == '+4482123456789')
    assert(normalize_phone_number('+4482123456789') == '+4482123456789')
    assert(normalize_phone_number('004482123456789') == '004482123456789')
    assert(normalize_phone_number('(082) 123456789') == '082123456789')
    assert(normalize_phone_number('0123456789') == '0123456789')
    assert(normalize_phone_number('123456789') == '123456789')
    assert(normalize_phone_number('23456789') == '23456789')
    assert(normalize_phone_number('3456789') == '3456789')
    assert(normalize_phone_number('456789') == '456789')

    assert(phone_numbers_equal('+44-82-123456789', '+44-82-123456789'))
    assert(phone_numbers_equal('+44-82-123456789', '+4482123456789'))
    assert(phone_numbers_equal('+44-82-123456789', '004482123456789'))
    assert(phone_numbers_equal('+44-82-123456789', '(082) 123456789'))
    assert(phone_numbers_equal('+44-82-123456789', '0123456789'))
    assert(phone_numbers_equal('+44-82-123456789', '123456789'))
    assert(phone_numbers_equal('+44-82-123456789', '93456789'))
    assert(phone_numbers_equal('+44-82-123456789', '3456789'))
    assert(not phone_numbers_equal('+44-82-123456789', '9456789'))
    assert(not phone_numbers_equal('+44-82-123456789', '456789'))
    assert(not phone_numbers_equal('+44-82-123456789', '56789'))
    assert(not phone_numbers_equal('+44-82-123456789', '6789'))
    assert(not phone_numbers_equal('+44-82-123456789', '789'))
    assert(not phone_numbers_equal('+44-82-123456789', '89'))
    assert(not phone_numbers_equal('+44-82-123456789', '9'))
    assert(not phone_numbers_equal('+44-82-123456789', ''))

    assert(normalize_phone_number('123.456.789') == '123456789')
    assert(normalize_phone_number('123 (456) 789') == '123456789')

    assert(normalize_phone_number('+123') == '+123')
    assert(normalize_phone_number('*31#+123') == '*31#+123')

    import sys
    out = sys.stdout
    sys.stdout = open('/dev/null', 'w')
    assert(normalize_phone_number('1+123') == '1123')
    assert(normalize_phone_number('foo:123') == 'foo:123')
    assert(normalize_phone_number('*31*+123') == '*31*123')
    sys.stdout.close()
    sys.stdout = out

    assert(phone_numbers_equal('+447654321', '+447654321'))
    assert(phone_numbers_equal('+447654321', '+447654321p1239#'))
    assert(phone_numbers_equal('+447654321', '+447654321  p12345#p123#'))
    assert(phone_numbers_equal('+447654321 ', '+447654321  p12345#p123#'))

    assert(phone_numbers_equal('1234567p0000000', '1234567'))
    assert(phone_numbers_equal('1234567p0000000', '1234567w9999999'))
    assert(phone_numbers_equal('1234567p0000000', '1234567w8'))
    assert(not phone_numbers_equal('1234567p0000000', '1234560p0000000'))

    assert(phone_numbers_equal('1234567', '1234567'))
    assert(phone_numbers_equal('1234567', '01234567'))
    assert(phone_numbers_equal('1234567', '+441234567'))

    assert(phone_numbers_equal('123456', '123456'))
    assert(phone_numbers_equal('123456', '123456p'))
    assert(phone_numbers_equal('123456', ' 123456'))
    assert(phone_numbers_equal('123456', ' 123456p1'))
    assert(not phone_numbers_equal('123456', '+44 123456'))
    assert(not phone_numbers_equal('123456', '9123456'))
    assert(not phone_numbers_equal('123456', '1234569'))
    assert(not phone_numbers_equal('+44123456', '0123456'))

    san_marino = ('0549 123 456',
                  '+378 0549 123 456',
                  '+39 0549 123 456',
                  '+39 549 123 456',
                  '0039 0549 123 456',
                  '011 39 0549 123 456',
                  '0011 39 0549 123 456',
                  '1666-378-0549-123-456',
                  '9903780549123456',
                  '0549 123 456 p1',
                  '#31# 0549 123 456')
    for i1 in san_marino:
        for i2 in san_marino:
            assert(phone_numbers_equal(i1, i2))

    print 'All the tests passed'
