"""
Sobre qué estados tiene sentido pedirle a Google que indexe.

No es «todo lo que no está indexado». Son los estados donde el pedido **puede
resolver algo**. El resto queda afuera del camino automático porque el pedido
está condenado de antemano: pedir la indexación de una página que declara
`noindex` es pelear contra la directiva del propio sitio, y el cupo que se gasta
ahí es cupo que le falta a una que sí podía prosperar.

La lista vive en un solo lugar y la consumen la tarea de fondo y la pantalla.
Escrita dos veces es de la clase de regla que se afloja: alguien agrega un
estado en la tarea, la pantalla sigue con la lista vieja, y las dos mitades del
producto dejan de decir lo mismo.

**Nada de esto prohíbe pedir a mano.** Los cinco desaconsejados se pueden enviar
igual, con la advertencia a la vista: quien opera el sitio puede saber algo que
nosotros no —que el `noindex` se acaba de sacar, por ejemplo—.
"""

from apps.sitemaps.models import CoverageState

#: Los cuatro que disparan el pedido solos, después de un recorrido.
AUTO_REQUEST_STATES = frozenset(
    {
        # Google la vio y decidió no incluirla. Es el caso típico, y el que
        # motivó este producto.
        CoverageState.CRAWLED_NOT_INDEXED,
        # La conoce y todavía no la visitó: el pedido es exactamente el empujón
        # que falta.
        CoverageState.DISCOVERED_NOT_INDEXED,
        # Motivo que no reconocemos. No hay razón para descartarlo de antemano.
        CoverageState.OTHER_NOT_INDEXED,
        # Ver `ONCE_ONLY_STATES`: entra, pero una sola vez.
        CoverageState.FETCH_ERROR,
    }
)

#: Estados que entran al automático **una sola vez por URL**.
#:
#: Si el fallo de descarga era pasajero, el pedido sirve. Si al siguiente
#: recorrido la URL sigue igual, el problema está en el sitio y no en el índice
#: de Google, y volver a pedirlo sólo quema cupo sin cambiar nada.
ONCE_ONLY_STATES = frozenset({CoverageState.FETCH_ERROR})

#: Los cinco que nunca se piden solos, cada uno con el motivo.
#:
#: El motivo se guarda con el estado, y no en un comentario, porque es lo que la
#: pantalla tiene que mostrar como advertencia cuando alguien lo pide igual: un
#: «no recomendado» sin la razón obliga a adivinar.
DISCOURAGED_STATES = {
    CoverageState.EXCLUDED_NOINDEX: 'EXCLUDED_NOINDEX',
    CoverageState.BLOCKED_ROBOTS: 'BLOCKED_ROBOTS',
    CoverageState.DUPLICATE_CANONICAL: 'DUPLICATE_CANONICAL',
    CoverageState.REDIRECT: 'REDIRECT',
    CoverageState.UNKNOWN: 'UNKNOWN',
}


def triggers_automatic_request(state: str) -> bool:
    """Si un recorrido que dejó una URL en este estado tiene que pedir su indexación."""
    return state in AUTO_REQUEST_STATES


def is_discouraged(state: str) -> bool:
    """Si pedir la indexación de una URL en este estado está desaconsejado."""
    return state in DISCOURAGED_STATES


def discouraged_reason(state: str) -> str:
    """El código del motivo por el que está desaconsejado, o vacío si no lo está."""
    return DISCOURAGED_STATES.get(state, '')
