from pydantic import BaseModel

from industrial_model.models import get_schema_properties
from tests.models import (
    DescribableEntity,
    Event,
    EventDetail,
    Msdp,
    ReportingSite,
    WritableEvent,
)

SEP = "|"


class _Car(BaseModel):
    model: str
    year: int
    owner: "SuperNestedModel"
    previous_owners: list["SuperNestedModel"] | None


class SuperNestedModel(DescribableEntity):
    parent: "SuperNestedModel"
    children: list["SuperNestedModel"]
    cars: list[_Car] | None


def test_get_schema_properties() -> None:
    for entity, expected_schema in _get_test_schema().items():
        schema = get_schema_properties(entity, SEP)
        assert schema == expected_schema, f"Expected {expected_schema}, got {schema}"


def _get_test_schema() -> dict[type[BaseModel], list[str]]:
    return {
        Msdp: ["effectiveDate", "externalId", "space"],
        DescribableEntity: ["description", "externalId", "name", "space"],
        ReportingSite: [
            "description",
            "externalId",
            "name",
            "space",
            "timeZone",
            "timeZone|description",
            "timeZone|externalId",
            "timeZone|name",
            "timeZone|space",
        ],
        EventDetail: [
            "externalId",
            "refDiscipline",
            "refDiscipline|description",
            "refDiscipline|externalId",
            "refDiscipline|name",
            "refDiscipline|space",
            "refEquipment",
            "refEquipment|description",
            "refEquipment|externalId",
            "refEquipment|name",
            "refEquipment|space",
            "refEventCode",
            "refEventCode|description",
            "refEventCode|externalId",
            "refEventCode|name",
            "refEventCode|space",
            "refMetricCode",
            "refMetricCode|description",
            "refMetricCode|externalId",
            "refMetricCode|name",
            "refMetricCode|space",
            "refSubCategoryL1",
            "refSubCategoryL1|description",
            "refSubCategoryL1|externalId",
            "refSubCategoryL1|name",
            "refSubCategoryL1|space",
            "refSubCategoryL2",
            "refSubCategoryL2|description",
            "refSubCategoryL2|externalId",
            "refSubCategoryL2|name",
            "refSubCategoryL2|space",
            "refSubCategoryL3",
            "refSubCategoryL3|description",
            "refSubCategoryL3|externalId",
            "refSubCategoryL3|name",
            "refSubCategoryL3|space",
            "refSubCategoryL4",
            "refSubCategoryL4|description",
            "refSubCategoryL4|externalId",
            "refSubCategoryL4|name",
            "refSubCategoryL4|space",
            "refSubCategoryL5",
            "refSubCategoryL5|description",
            "refSubCategoryL5|externalId",
            "refSubCategoryL5|name",
            "refSubCategoryL5|space",
            "space",
        ],
        Event: [
            "externalId",
            "refMaterial",
            "refMaterial|description",
            "refMaterial|externalId",
            "refMaterial|name",
            "refMaterial|space",
            "refOEEEventDetail",
            "refOEEEventDetail|externalId",
            "refOEEEventDetail|refDiscipline",
            "refOEEEventDetail|refDiscipline|description",
            "refOEEEventDetail|refDiscipline|externalId",
            "refOEEEventDetail|refDiscipline|name",
            "refOEEEventDetail|refDiscipline|space",
            "refOEEEventDetail|refEquipment",
            "refOEEEventDetail|refEquipment|description",
            "refOEEEventDetail|refEquipment|externalId",
            "refOEEEventDetail|refEquipment|name",
            "refOEEEventDetail|refEquipment|space",
            "refOEEEventDetail|refEventCode",
            "refOEEEventDetail|refEventCode|description",
            "refOEEEventDetail|refEventCode|externalId",
            "refOEEEventDetail|refEventCode|name",
            "refOEEEventDetail|refEventCode|space",
            "refOEEEventDetail|refMetricCode",
            "refOEEEventDetail|refMetricCode|description",
            "refOEEEventDetail|refMetricCode|externalId",
            "refOEEEventDetail|refMetricCode|name",
            "refOEEEventDetail|refMetricCode|space",
            "refOEEEventDetail|refSubCategoryL1",
            "refOEEEventDetail|refSubCategoryL1|description",
            "refOEEEventDetail|refSubCategoryL1|externalId",
            "refOEEEventDetail|refSubCategoryL1|name",
            "refOEEEventDetail|refSubCategoryL1|space",
            "refOEEEventDetail|refSubCategoryL2",
            "refOEEEventDetail|refSubCategoryL2|description",
            "refOEEEventDetail|refSubCategoryL2|externalId",
            "refOEEEventDetail|refSubCategoryL2|name",
            "refOEEEventDetail|refSubCategoryL2|space",
            "refOEEEventDetail|refSubCategoryL3",
            "refOEEEventDetail|refSubCategoryL3|description",
            "refOEEEventDetail|refSubCategoryL3|externalId",
            "refOEEEventDetail|refSubCategoryL3|name",
            "refOEEEventDetail|refSubCategoryL3|space",
            "refOEEEventDetail|refSubCategoryL4",
            "refOEEEventDetail|refSubCategoryL4|description",
            "refOEEEventDetail|refSubCategoryL4|externalId",
            "refOEEEventDetail|refSubCategoryL4|name",
            "refOEEEventDetail|refSubCategoryL4|space",
            "refOEEEventDetail|refSubCategoryL5",
            "refOEEEventDetail|refSubCategoryL5|description",
            "refOEEEventDetail|refSubCategoryL5|externalId",
            "refOEEEventDetail|refSubCategoryL5|name",
            "refOEEEventDetail|refSubCategoryL5|space",
            "refOEEEventDetail|space",
            "refProcessType",
            "refProcessType|description",
            "refProcessType|externalId",
            "refProcessType|name",
            "refProcessType|space",
            "refProduct",
            "refProduct|description",
            "refProduct|externalId",
            "refProduct|name",
            "refProduct|space",
            "refReportingLine",
            "refReportingLine|description",
            "refReportingLine|externalId",
            "refReportingLine|name",
            "refReportingLine|space",
            "refReportingLocation",
            "refReportingLocation|description",
            "refReportingLocation|externalId",
            "refReportingLocation|name",
            "refReportingLocation|space",
            "refSite",
            "refSite|description",
            "refSite|externalId",
            "refSite|name",
            "refSite|space",
            "refSite|timeZone",
            "refSite|timeZone|description",
            "refSite|timeZone|externalId",
            "refSite|timeZone|name",
            "refSite|timeZone|space",
            "refUnit",
            "refUnit|description",
            "refUnit|externalId",
            "refUnit|name",
            "refUnit|space",
            "space",
            "startDateTime",
        ],
        WritableEvent: [
            "externalId",
            "refOEEEventDetail",
            "refOEEEventDetail|externalId",
            "refOEEEventDetail|refDiscipline",
            "refOEEEventDetail|refDiscipline|description",
            "refOEEEventDetail|refDiscipline|externalId",
            "refOEEEventDetail|refDiscipline|name",
            "refOEEEventDetail|refDiscipline|space",
            "refOEEEventDetail|refEquipment",
            "refOEEEventDetail|refEquipment|description",
            "refOEEEventDetail|refEquipment|externalId",
            "refOEEEventDetail|refEquipment|name",
            "refOEEEventDetail|refEquipment|space",
            "refOEEEventDetail|refEventCode",
            "refOEEEventDetail|refEventCode|description",
            "refOEEEventDetail|refEventCode|externalId",
            "refOEEEventDetail|refEventCode|name",
            "refOEEEventDetail|refEventCode|space",
            "refOEEEventDetail|refMetricCode",
            "refOEEEventDetail|refMetricCode|description",
            "refOEEEventDetail|refMetricCode|externalId",
            "refOEEEventDetail|refMetricCode|name",
            "refOEEEventDetail|refMetricCode|space",
            "refOEEEventDetail|refSubCategoryL1",
            "refOEEEventDetail|refSubCategoryL1|description",
            "refOEEEventDetail|refSubCategoryL1|externalId",
            "refOEEEventDetail|refSubCategoryL1|name",
            "refOEEEventDetail|refSubCategoryL1|space",
            "refOEEEventDetail|refSubCategoryL2",
            "refOEEEventDetail|refSubCategoryL2|description",
            "refOEEEventDetail|refSubCategoryL2|externalId",
            "refOEEEventDetail|refSubCategoryL2|name",
            "refOEEEventDetail|refSubCategoryL2|space",
            "refOEEEventDetail|refSubCategoryL3",
            "refOEEEventDetail|refSubCategoryL3|description",
            "refOEEEventDetail|refSubCategoryL3|externalId",
            "refOEEEventDetail|refSubCategoryL3|name",
            "refOEEEventDetail|refSubCategoryL3|space",
            "refOEEEventDetail|refSubCategoryL4",
            "refOEEEventDetail|refSubCategoryL4|description",
            "refOEEEventDetail|refSubCategoryL4|externalId",
            "refOEEEventDetail|refSubCategoryL4|name",
            "refOEEEventDetail|refSubCategoryL4|space",
            "refOEEEventDetail|refSubCategoryL5",
            "refOEEEventDetail|refSubCategoryL5|description",
            "refOEEEventDetail|refSubCategoryL5|externalId",
            "refOEEEventDetail|refSubCategoryL5|name",
            "refOEEEventDetail|refSubCategoryL5|space",
            "refOEEEventDetail|space",
            "refReportingLine",
            "refReportingLine|description",
            "refReportingLine|externalId",
            "refReportingLine|name",
            "refReportingLine|space",
            "refSite",
            "refSite|description",
            "refSite|externalId",
            "refSite|name",
            "refSite|space",
            "refSite|timeZone",
            "refSite|timeZone|description",
            "refSite|timeZone|externalId",
            "refSite|timeZone|name",
            "refSite|timeZone|space",
            "space",
            "startDateTime",
        ],
        SuperNestedModel: [
            "cars",
            "cars|model",
            "cars|owner",
            "cars|owner|cars",
            "cars|owner|cars|model",
            "cars|owner|cars|owner",
            "cars|owner|cars|previous_owners",
            "cars|owner|cars|year",
            "cars|owner|children",
            "cars|owner|description",
            "cars|owner|externalId",
            "cars|owner|name",
            "cars|owner|parent",
            "cars|owner|parent|cars",
            "cars|owner|parent|cars|model",
            "cars|owner|parent|cars|owner",
            "cars|owner|parent|cars|previous_owners",
            "cars|owner|parent|cars|year",
            "cars|owner|parent|children",
            "cars|owner|parent|description",
            "cars|owner|parent|externalId",
            "cars|owner|parent|name",
            "cars|owner|parent|parent",
            "cars|owner|parent|parent|cars",
            "cars|owner|parent|parent|cars|model",
            "cars|owner|parent|parent|cars|owner",
            "cars|owner|parent|parent|cars|previous_owners",
            "cars|owner|parent|parent|cars|year",
            "cars|owner|parent|parent|children",
            "cars|owner|parent|parent|description",
            "cars|owner|parent|parent|externalId",
            "cars|owner|parent|parent|name",
            "cars|owner|parent|parent|parent",
            "cars|owner|parent|parent|space",
            "cars|owner|parent|space",
            "cars|owner|space",
            "cars|previous_owners",
            "cars|year",
            "children",
            "children|cars",
            "children|cars|model",
            "children|cars|owner",
            "children|cars|previous_owners",
            "children|cars|year",
            "children|children",
            "children|description",
            "children|externalId",
            "children|name",
            "children|parent",
            "children|parent|cars",
            "children|parent|cars|model",
            "children|parent|cars|owner",
            "children|parent|cars|previous_owners",
            "children|parent|cars|year",
            "children|parent|children",
            "children|parent|description",
            "children|parent|externalId",
            "children|parent|name",
            "children|parent|parent",
            "children|parent|space",
            "children|space",
            "description",
            "externalId",
            "name",
            "parent",
            "parent|cars",
            "parent|cars|model",
            "parent|cars|owner",
            "parent|cars|previous_owners",
            "parent|cars|year",
            "parent|children",
            "parent|description",
            "parent|externalId",
            "parent|name",
            "parent|parent",
            "parent|parent|cars",
            "parent|parent|cars|model",
            "parent|parent|cars|owner",
            "parent|parent|cars|previous_owners",
            "parent|parent|cars|year",
            "parent|parent|children",
            "parent|parent|description",
            "parent|parent|externalId",
            "parent|parent|name",
            "parent|parent|parent",
            "parent|parent|space",
            "parent|space",
            "space",
        ],
    }
