#!/usr/bin/env python3

# Check the length of the IBAN
def check_iban_length(iban):
    iban_lengths = {
        'AT': 20,  # Austria
        'DE': 22,  # Germany
        'CH': 21,  # Switzerland
    }
    country_code = iban[:2]
    if country_code not in iban_lengths:
        print('Country code not found')
        return False
    elif len(iban) != iban_lengths[country_code]:
        print('IBAN length is incorrect')
        return False
    else:
        return True

# Removes spaces and converts to uppercase
def tidy_iban(iban):
    return iban.replace(' ', '').upper()

# test the checksum
def test_checksum(iban):
    iban = iban[4:] + iban[:4]
    digit_string = ''
    # loop over the IBAN and replace letters with numbers
    for c in iban:
        if c.isdigit():
            digit_string += c
        else:
            digit_string += str(ord(c) - 55)
    # convert the string to an integer and test if modulo 97 is 1
    return int(digit_string) % 97 == 1

# Verify the IBAN
def verify_iban(iban):
    iban = tidy_iban(iban)
    return check_iban_length(iban) and test_checksum(iban)

# test code
def test_iban_validation():
    valid_ibans = [
        'AT611904300234573201', 'AT483200000012345864', 'at47 7604 0264 4030 8794',
        'de89 370400440 532013000', 'DE44500105175407324931', 'DE75512108001245126199',
        'CH9300762011623852957', 'CH5604835012345678009', 
    ]
    invalid_ibans = [
        'AT61 1904 3002 3457 0320', 'AT12 3456 7890 1234 5678', 'AT6119040000003201111', 
        'DE8937040044053201300', 'DE12345678901234567890', 'DE445001051754073249311',
        'CH930076201162385295', 'CH12345678901234567890', 'CH56048350123456780091'
    ]
    for iban in valid_ibans:
        assert verify_iban(iban), f"Valid IBAN failed: {iban}"
    
    for iban in invalid_ibans:
        assert not verify_iban(iban), f"Invalid IBAN passed: {iban}"
    
    print("All tests passed!")

# Main code starts here
test_iban_validation()