#!/usr/bin/env python3
# --------------------( LICENSE                            )--------------------
# Copyright (c) 2014-2024 Beartype authors.
# See "LICENSE" for further details.

'''
Beartype **type-checking expression snippet classes** (i.e., low-level classes
dynamically and efficiently generating substrings intended to be interpolated
into boolean expressions type-checking arbitrary objects against various type
hints).

This private submodule is *not* intended for importation by downstream callers.
'''

# ....................{ IMPORTS                            }....................
from beartype._check.checkmagic import VAR_NAME_PITH_PREFIX

# ....................{ SUBCLASSES                         }....................
class PithIndexToVarName(dict):
    '''
    **Local pith variable name cache** (i.e., dictionary mapping from the
    1-based index uniquely identifying each **pith** (i.e., current parameter or
    return value *or* item contained in the current parameter or return value
    type-checked by the current call in the body of a runtime type-checker
    dynamically generated by :mod:`beartype`) to the corresponding name of a
    prospective local variable assigned that value in that body).

    See Also
    --------
    :data:`.PITH_INDEX_TO_VAR_NAME`
        Singleton instance of this dictionary subclass.
    '''

    # ....................{ DUNDERS                        }....................
    def __missing__(self, pith_index: int) -> str:
        '''
        Dunder method explicitly called by the superclass
        :meth:`dict.__getitem__` method implicitly called on the first ``[``-
        and ``]``-delimited attempt to access a local pith variable name
        uniquely identified by the passed 1-based index.

        Parameters
        ----------
        pith_index : int
            1-based index suffixing the local pith variable name to be created,
            cached, and returned.

        Returns
        -------
        str
            Prospective name of this local pith variable.

        Raises
        ------
        AssertionError
            If either:

            * ``pith_level`` is *not* an integer.
            * ``pith_level`` is a **negative integer** (i.e., less than 0).
        '''
        assert isinstance(pith_index, int), f'{repr(pith_index)} not integer.'
        assert pith_index >= 0, f'{pith_index} < 0.'
        # print(f'Generating indentation level {indent_level}...')

        # Prospective name of this local pith variable.
        pith_var_name = f'{VAR_NAME_PITH_PREFIX}{pith_index}'

        # Cache this name.
        self[pith_index] = pith_var_name

        # Return this name.
        return pith_var_name

# ....................{ MAPPINGS                           }....................
PITH_INDEX_TO_VAR_NAME = PithIndexToVarName()
'''
**Indentation cache singleton** (i.e., global dictionary efficiently mapping
from 1-based indentation levels to the corresponding indentation string
constant).

Caveats
-------
**Indentation string constants should always be accessed via this cache rather
than manually generated.** This cache dynamically creates and efficiently caches
indentation string constants on the first access of those constants, obviating
the performance cost of string formatting required to create these constants.

Examples
--------
.. code-block:: pycon

   >>> from beartype._check.code.snip.codesnipcls import PITH_INDEX_TO_VAR_NAME
   >>> PITH_INDEX_TO_VAR_NAME[1]
   '__beartype_pith_1'
   >>> PITH_INDEX_TO_VAR_NAME[2]
   '__beartype_pith_2'
'''
