import re

from esphome import config_validation as cv
from esphome.const import CONF_ARGS, CONF_FORMAT

CONF_IF_NAN = "if_nan"


f_regex = re.compile(
    r"""
    (                                   # start of capture group 1
    %                                   # literal "%"
    [-+0 #]{0,5}                        # optional flags
    (?:\d+|\*)?                         # width
    (?:\.(?:\d+|\*))?                   # precision
    (?:hh|h|ll|l|j|z|t|L|w|I|I32|I64)?  # size
    f                                   # type
    )
    """,
    flags=re.VERBOSE,
)
c_regex = re.compile(
    r"""
    (                                   # start of capture group 1
    %                                   # literal "%"
    [-+0 #]{0,5}                        # optional flags
    (?:\d+|\*)?                         # width
    (?:\.(?:\d+|\*))?                   # precision
    (?:hh|h|ll|l|j|z|t|L|w|I|I32|I64)?  # size
    [cCdiouxXeEfgGaAnpsSZ]              # type
    )
    """,
    flags=re.VERBOSE,
)


def validate_printf(value):
    format_string = value[CONF_FORMAT]
    matches = c_regex.findall(format_string)
    if len(matches) != len(value[CONF_ARGS]):
        raise cv.Invalid(
            f"Found {len(matches)} printf-patterns ({', '.join(matches)}), but {len(value[CONF_ARGS])} args were given!"
        )

    if value.get(CONF_IF_NAN) and len(f_regex.findall(format_string)) != 1:
        raise cv.Invalid(
            "Use of 'if_nan' requires a single valid printf-pattern of type %f"
        )
    return value
