# Path: notifications_utils/recipients.py
# class RecipientCSV():
# class Row(InsensitiveDict):
# class Cell():
# class InvalidEmailError(Exception):
# class InvalidPhoneError(InvalidEmailError):
# class InvalidAddressError(InvalidEmailError):
#     def __init__(
#         self,
#         file_data,
#         template,
#         max_errors_shown=20,
#         max_initial_rows_shown=10,
#         guestlist=None,
#         remaining_messages=sys.maxsize,
#         allow_international_sms=False,
#         allow_international_letters=False,
#         should_validate=True,
#     ):
#     def __len__(self):
#     def __getitem__(self, requested_index):
#     def guestlist(self):
#     def guestlist(self, value):
#     def template(self):
#     def template(self, value):
#     def placeholders(self):
#     def placeholders(self, value):
#     def has_errors(self):
#     def allowed_to_send_to(self):
#     def rows(self):
#     def _rows(self):
#     def get_rows(self):
#     def more_rows_than_can_send(self):
#     def too_many_rows(self):
#     def initial_rows(self):
#     def displayed_rows(self):
#     def _filter_rows(self, attr):
#     def rows_with_errors(self):
#     def rows_with_bad_recipients(self):
#     def rows_with_missing_data(self):
#     def rows_with_message_too_long(self):
#     def rows_with_empty_message(self):
#     def initial_rows_with_errors(self):
#     def _raw_column_headers(self):
#     def column_headers(self):
#     def column_headers_as_column_keys(self):
#     def missing_column_headers(self):
#     def duplicate_recipient_column_headers(self):
#     def is_address_column(self, key):
#     def count_of_required_recipient_columns(self):
#     def has_recipient_columns(self):
#     def _get_error_for_field(self, key, value):  # noqa: C901
#     def __init__(
#         self,
#         row_dict,
#         *,
#         index,
#         error_fn,
#         recipient_column_headers,
#         placeholders,
#         template,
#         allow_international_letters,
#         validate_row=True,
#     ):
#     def __getitem__(self, key):
#     def get(self, key, default=None):
#     def has_error(self):
#     def has_bad_recipient(self):
#     def has_bad_postal_address(self):
#     def has_error_spanning_multiple_cells(self):
#     def has_missing_data(self):
#     def recipient(self):
#     def as_postal_address(self):
#     def personalisation(self):
#     def recipient_and_personalisation(self):
#     def __init__(
#         self,
#         key=None,
#         value=None,
#         error_fn=None,
#         placeholders=None
#     ):
#     def __eq__(self, other):
#     def recipient_error(self):
#     def __init__(self, message=None):
# def normalise_phone_number(number):
# def is_uk_phone_number(number):
# def get_international_phone_info(number):
# def _is_a_crown_dependency_number(number):
# def get_international_prefix(number):
# def get_billable_units_for_prefix(prefix):
# def use_numeric_sender(number):
# def validate_uk_phone_number(number):
# def validate_phone_number(number, international=False):
# def try_validate_and_format_phone_number(number, international=None, log_msg=None):
# def validate_email_address(email_address):  # noqa (C901 too complex)
# def format_email_address(email_address):
# def validate_and_format_email_address(email_address):
# def format_recipient(recipient):
# def format_phone_number_human_readable(phone_number):
# def allowed_to_send_to(recipient, allowlist):
# def insert_or_append_to_dict(dict_, key, value):
# CROWN_DEPENDENCY_RANGES = ['7781', '7839', '7911', '7509', '7797', '7937', '7700', '7829', '7624', '7524', '7924']


import pytest
from notifications_utils.recipients import (
    InvalidEmailError,
    InvalidPhoneError,
    allowed_to_send_to,
    format_phone_number_human_readable,
    format_recipient,
    get_international_phone_info,
    international_phone_info,
    is_uk_phone_number,
    normalise_phone_number,
    try_validate_and_format_phone_number,
    validate_and_format_phone_number,
    validate_email_address,
    validate_phone_number,
)
    ('23051234567', '23051234567'),
])
def test_valid_international_phone_number_can_be_formatted_consistently(phone_number, expected_formatted):
    assert validate_and_format_phone_number(
        phone_number, international=True
    ) == expected_formatted


@pytest.mark.parametrize("phone_number, error_message", invalid_uk_phone_numbers)
@pytest.mark.parametrize("extra_args", [
    {},
    {'international': False},
])
def test_phone_number_rejects_invalid_values(extra_args, phone_number, error_message):
    with pytest.raises(InvalidPhoneError) as e:
        validate_phone_number(phone_number, **extra_args)
    assert error_message == str(e.value)


@pytest.mark.parametrize("phone_number, error_message", invalid_phone_numbers)
def test_phone_number_rejects_invalid_international_values(phone_number, error_message):
    with pytest.raises(InvalidPhoneError) as e:
        validate_phone_number(phone_number, international=True)
    assert error_message == str(e.value)


@pytest.mark.parametrize("email_address", valid_email_addresses)
def test_validate_email_address_accepts_valid(email_address):
    try:
        assert validate_email_address(email_address) == email_address

# Path: notifications_utils/recipients.py
# class RecipientCSV():
# class Row(InsensitiveDict):
# class Cell():
# class InvalidEmailError(Exception):
# class InvalidPhoneError(InvalidEmailError):
# class InvalidAddressError(InvalidEmailError):
#     def __init__(
#         self,
#         file_data,
#         template,
#         max_errors_shown=20,
#         max_initial_rows_shown=10,
#         guestlist=None,
#         remaining_messages=sys.maxsize,
#         allow_international_sms=False,
#         allow_international_letters=False,
#         should_validate=True,
#     ):
#     def __len__(self):
#     def __getitem__(self, requested_index):
#     def guestlist(self):
#     def guestlist(self, value):
#     def template(self):
#     def template(self, value):
#     def placeholders(self):
#     def placeholders(self, value):
#     def has_errors(self):
#     def allowed_to_send_to(self):
#     def rows(self):
#     def _rows(self):
#     def get_rows(self):
#     def more_rows_than_can_send(self):
#     def too_many_rows(self):
#     def initial_rows(self):
#     def displayed_rows(self):
#     def _filter_rows(self, attr):
#     def rows_with_errors(self):
#     def rows_with_bad_recipients(self):
#     def rows_with_missing_data(self):
#     def rows_with_message_too_long(self):
#     def rows_with_empty_message(self):
#     def initial_rows_with_errors(self):
#     def _raw_column_headers(self):
#     def column_headers(self):
#     def column_headers_as_column_keys(self):
#     def missing_column_headers(self):
#     def duplicate_recipient_column_headers(self):
#     def is_address_column(self, key):
#     def count_of_required_recipient_columns(self):
#     def has_recipient_columns(self):
#     def _get_error_for_field(self, key, value):  # noqa: C901
#     def __init__(
#         self,
#         row_dict,
#         *,
#         index,
#         error_fn,
#         recipient_column_headers,
#         placeholders,
#         template,
#         allow_international_letters,
#         validate_row=True,
#     ):
#     def __getitem__(self, key):
#     def get(self, key, default=None):
#     def has_error(self):
#     def has_bad_recipient(self):
#     def has_bad_postal_address(self):
#     def has_error_spanning_multiple_cells(self):
#     def has_missing_data(self):
#     def recipient(self):
#     def as_postal_address(self):
#     def personalisation(self):
#     def recipient_and_personalisation(self):
#     def __init__(
#         self,
#         key=None,
#         value=None,
#         error_fn=None,
#         placeholders=None
#     ):
#     def __eq__(self, other):
#     def recipient_error(self):
#     def __init__(self, message=None):
# def normalise_phone_number(number):
# def is_uk_phone_number(number):
# def get_international_phone_info(number):
# def _is_a_crown_dependency_number(number):
# def get_international_prefix(number):
# def get_billable_units_for_prefix(prefix):
# def use_numeric_sender(number):
# def validate_uk_phone_number(number):
# def validate_phone_number(number, international=False):
# def try_validate_and_format_phone_number(number, international=None, log_msg=None):
# def validate_email_address(email_address):  # noqa (C901 too complex)
# def format_email_address(email_address):
# def validate_and_format_email_address(email_address):
# def format_recipient(recipient):
# def format_phone_number_human_readable(phone_number):
# def allowed_to_send_to(recipient, allowlist):
# def insert_or_append_to_dict(dict_, key, value):
# CROWN_DEPENDENCY_RANGES = ['7781', '7839', '7911', '7509', '7797', '7937', '7700', '7829', '7624', '7524', '7924']


# Path: tests/test_recipient_validation.py
import pytest
from notifications_utils.recipients import (
    InvalidEmailError,
    InvalidPhoneError,
    allowed_to_send_to,
    format_phone_number_human_readable,
    format_recipient,
    get_international_phone_info,
    international_phone_info,
    is_uk_phone_number,
    normalise_phone_number,
    try_validate_and_format_phone_number,
    validate_and_format_phone_number,
    validate_email_address,
    validate_phone_number,
)

    ('23051234567', '23051234567'),
])
def test_valid_international_phone_number_can_be_formatted_consistently(phone_number, expected_formatted):
    assert validate_and_format_phone_number(
        phone_number, international=True
    ) == expected_formatted


@pytest.mark.parametrize("phone_number, error_message", invalid_uk_phone_numbers)
@pytest.mark.parametrize("extra_args", [
    {},
    {'international': False},
])
def test_phone_number_rejects_invalid_values(extra_args, phone_number, error_message):
    with pytest.raises(InvalidPhoneError) as e:
        validate_phone_number(phone_number, **extra_args)
    assert error_message == str(e.value)


@pytest.mark.parametrize("phone_number, error_message", invalid_phone_numbers)
def test_phone_number_rejects_invalid_international_values(phone_number, error_message):
    with pytest.raises(InvalidPhoneError) as e:
        validate_phone_number(phone_number, international=True)
    assert error_message == str(e.value)


@pytest.mark.parametrize("email_address", valid_email_addresses)
def test_validate_email_address_accepts_valid(email_address):
    try:
        assert validate_email_address(email_address) == email_address

    except InvalidEmailError: