#!/usr/bin/env python3

import sys
import re

# Mapping of country codes to IBAN lengths
IBAN_LENGTHS = {
    'AT': 20,  # Austria
    'DE': 22,  # Germany
    'CH': 21,  # Switzerland
}

def normalize_iban(iban: str) -> str:
    """Remove spaces and convert to uppercase."""
    return re.sub(r'\s+', '', iban).upper()

def validate_country_code(iban: str) -> None:
    """Check that the IBAN starts with a known country code."""
    country_code = iban[:2]
    if country_code not in IBAN_LENGTHS:
        print('Country code not found')
        sys.exit(1)

def validate_length(iban: str) -> None:
    """Ensure the IBAN has the correct length for its country."""
    country_code = iban[:2]
    expected_length = IBAN_LENGTHS[country_code]
    if len(iban) != expected_length:
        print('IBAN length is incorrect')
        sys.exit(1)

def convert_to_digits(iban: str) -> str:
    """Move first four characters to the end and convert letters to digits."""
    rearranged = iban[4:] + iban[:4]
    digit_chars = []
    for ch in rearranged:
        if ch.isdigit():
            digit_chars.append(ch)
        else:
            digit_chars.append(str(ord(ch) - 55))  # A=10, B=11, ...
    return ''.join(digit_chars)

def modulo_97(number_str: str) -> int:
    """Compute the remainder of a large integer when divided by 97."""
    remainder = 0
    for char in number_str:
        remainder = (remainder * 10 + int(char)) % 97
    return remainder

def is_iban_valid(iban: str) -> bool:
    """Return True if the IBAN passes the checksum test."""
    digit_string = convert_to_digits(iban)
    return modulo_97(digit_string) == 1

def main() -> None:
    iban = 'AT483200000012345864'  # Example IBAN; replace with input as needed
    iban = normalize_iban(iban)

    validate_country_code(iban)
    validate_length(iban)

    if is_iban_valid(iban):
        print('IBAN is valid')
    else:
        print('IBAN is invalid')

if __name__ == '__main__':
    main()