# Path: src/render/main.py
# class MessageTooLong(ValueError):
#     pass
# 
# class SmsLength:
#     length: int
#     parts: int
# 
# def sms_length(msg: str) -> SmsLength:
#     """
#     :param msg: msg string
#     :return: tuple (length of the message, number of multi-part SMSs required)
#     """
#     length = 0
#     for c in msg:
#         if c in BASIC_CHARACTERS:
#             length += 1
#         elif c in EXTENSION_CHARACTERS:
#             length += 2
#         # in theory all other characters are unavailable in GSM 03.38 and will be stripped out
# 
#     for msg_parts, max_length in MULTIPART_LENGTHS:
#         if length <= max_length:
#             return SmsLength(length, msg_parts)
#     raise MessageTooLong(f'message length {length} exceeds maximum multi-part SMS length {max_length}')


import pytest
from src.render.main import MessageTooLong, SmsLength, sms_length

def idfn(v):
    if isinstance(v, str):
        return f'{v[:20]}:{len(v)}'


@pytest.mark.parametrize(
    'msg, length, sms_count',
    [
        ('123', 3, 1),
        ('123\n456', 8, 1),
        ('123😀', 3, 1),
        ('123®', 4, 1),
        ('123{', 5, 1),
        ('{}', 4, 1),
        ('a' * 160, 160, 1),
        ('b' * 161, 161, 2),
        ('c' * 306, 306, 2),
        ('d' * 307, 307, 3),
        ('e' * 1377, 1377, 9),
        ('{' * 100, 200, 2),
    ],
    ids=idfn,
)
def test_sms_lengths(msg, length, sms_count):
    assert sms_length(msg) == SmsLength(length, sms_count)


def test_sms_too_long():
    with pytest.raises(MessageTooLong) as exc_info:

# Path: src/render/main.py
# class MessageTooLong(ValueError):
#     pass
# 
# class SmsLength:
#     length: int
#     parts: int
# 
# def sms_length(msg: str) -> SmsLength:
#     """
#     :param msg: msg string
#     :return: tuple (length of the message, number of multi-part SMSs required)
#     """
#     length = 0
#     for c in msg:
#         if c in BASIC_CHARACTERS:
#             length += 1
#         elif c in EXTENSION_CHARACTERS:
#             length += 2
#         # in theory all other characters are unavailable in GSM 03.38 and will be stripped out
# 
#     for msg_parts, max_length in MULTIPART_LENGTHS:
#         if length <= max_length:
#             return SmsLength(length, msg_parts)
#     raise MessageTooLong(f'message length {length} exceeds maximum multi-part SMS length {max_length}')


# Path: tests/test_render.py
import pytest
from src.render.main import MessageTooLong, SmsLength, sms_length


def idfn(v):
    if isinstance(v, str):
        return f'{v[:20]}:{len(v)}'


@pytest.mark.parametrize(
    'msg, length, sms_count',
    [
        ('123', 3, 1),
        ('123\n456', 8, 1),
        ('123😀', 3, 1),
        ('123®', 4, 1),
        ('123{', 5, 1),
        ('{}', 4, 1),
        ('a' * 160, 160, 1),
        ('b' * 161, 161, 2),
        ('c' * 306, 306, 2),
        ('d' * 307, 307, 3),
        ('e' * 1377, 1377, 9),
        ('{' * 100, 200, 2),
    ],
    ids=idfn,
)
def test_sms_lengths(msg, length, sms_count):
    assert sms_length(msg) == SmsLength(length, sms_count)


def test_sms_too_long():
    with pytest.raises(MessageTooLong) as exc_info:

        sms_length('x' * 1378)