import re
from collections.abc import Mapping

from cognite.client import data_modeling as dm
from rdflib import Namespace, URIRef

DEFAULT_SPACE_URI = "http://purl.org/cognite/space/{space}#"
SPACE_URI_PATTERN = re.compile(r"http://purl.org/cognite/space/(?P<space>[^#]+)#$")
DEFAULT_RAW_URI = "http://purl.org/cognite/raw#"

DEFAULT_NAMESPACE = Namespace("http://purl.org/cognite/neat/")
DEFAULT_BASE_URI = URIRef(DEFAULT_NAMESPACE)

# The number of instances that should be left as a margin when writing to CDF through the DMS API.
DMS_INSTANCE_LIMIT_MARGIN = 1_000_000


def get_raw_namespace(db_name: str, table_name: str) -> str:
    """Get namespaced URI for RAW table to enable table-specific SHACL targeting.

    Args:
        db_name: RAW database name
        table_name: RAW table name

    Returns:
        Namespace URI string (e.g., "http://purl.org/cognite/raw/iot/sensors/")
    """
    return f"http://purl.org/cognite/raw/{db_name}/{table_name}/"


READONLY_PROPERTIES_BY_CONTAINER: Mapping[dm.ContainerId, frozenset[str]] = {
    dm.ContainerId("cdf_cdm", "CogniteAsset"): frozenset(
        {"assetHierarchy_root", "assetHierarchy_path", "assetHierarchy_path_last_updated_time"}
    ),
    dm.ContainerId("cdf_cdm", "CogniteFile"): frozenset({"isUploaded", "uploadedTime"}),
}


def is_readonly_property(container: dm.ContainerId, property_: str) -> bool:
    return container in READONLY_PROPERTIES_BY_CONTAINER and property_ in READONLY_PROPERTIES_BY_CONTAINER[container]
