"""Shared pytest fixtures."""

from __future__ import annotations

import pytest
from sqlalchemy import create_engine, event
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.orm import Session, sessionmaker

from db.base import Base
from db.models import (
    BrochureTaxonomyGroup,
    BrochureTaxonomyGroupSku,
    CatalogNormalizationProfile,
    CatalogNormalizationRule,
    CatalogNormalizationRuleTarget,
    CatalogResolvedField,
    CatalogReviewQueueItem,
    CatalogValueAlias,
    CollectionCommerceProfile,
    ChannelCatalogPolicy,
    ChannelCatalogPolicyScope,
    ChannelJob,
    ChannelProjectionRow,
    ChannelProjectionRun,
    ChannelPublishState,
    ChannelSchedule,
    ChannelShellProduct,
    ChannelSkuMapping,
    ChannelSkuPrefixMapping,
    ChannelListingPath,
    ChannelListingPathTarget,
    ChannelTaxonomyMapping,
    ChannelVariationPolicy,
    ChannelAttributeAlias,
    CollectionLandingPage,
    CollectionSkuOverride,
    MasterProductCollectionMembership,
    ListingIntersectionRule,
    MagentoAttributeOptionRegistry,
    MagentoAttributeRegistry,
    MagentoCategoryRegistry,
    MagentoConnection,
    ManualTaxonomyAssignment,
    ManualTaxonomyAssignmentCollection,
    ManualAttributeLockRule,
    ManualAttributeLockTarget,
    ManualAttributeVocabulary,
    ManualAttributeVocabularyValue,
    MasterAttributeDefinition,
    MasterAssemblyMode,
    MasterBrand,
    MasterCatalogIntentRun,
    MasterCollectionRegistry,
    MasterLocationRegistry,
    MasterProduct,
    MasterProductAttributeValue,
    MasterProductAssociation,
    MasterProductImage,
    MasterProductFamily,
    MasterProductLocationAvailability,
    MasterProductOverride,
    MasterProductPrice,
    MasterProductRelation,
    MasterProductType,
    MasterStaticFieldMapping,
    MasterTaxonomyChannelLink,
    MasterTaxonomyNode,
    MasterTaxonomyPathAlias,
    ProductChannelAssignment,
    ProductChannelTaxonomyAssignment,
    ProductListingPathAssignment,
    ShopifyAttributeRegistry,
    ShopifyCollectionRegistry,
    ShopifyConnection,
    ShopifyTaxonomyRegistry,
)


@compiles(JSONB, "sqlite")
def _compile_jsonb_sqlite(element, compiler, **kw):
    return "JSON"


_CATALOG_INTENT_TABLES = [
    CatalogNormalizationProfile.__table__,
    CatalogNormalizationRule.__table__,
    CatalogNormalizationRuleTarget.__table__,
    CatalogResolvedField.__table__,
    CatalogReviewQueueItem.__table__,
    CatalogValueAlias.__table__,
    CollectionCommerceProfile.__table__,
    BrochureTaxonomyGroup.__table__,
    BrochureTaxonomyGroupSku.__table__,
    ChannelCatalogPolicy.__table__,
    ChannelCatalogPolicyScope.__table__,
    ChannelProjectionRow.__table__,
    ChannelProjectionRun.__table__,
    ChannelPublishState.__table__,
    ChannelShellProduct.__table__,
    ChannelVariationPolicy.__table__,
    MasterAssemblyMode.__table__,
    MasterBrand.__table__,
    MasterProductFamily.__table__,
    MasterProductType.__table__,
    MasterStaticFieldMapping.__table__,
    MasterCollectionRegistry.__table__,
    MasterProduct.__table__,
    MasterProductAttributeValue.__table__,
    MasterProductAssociation.__table__,
    MasterProductImage.__table__,
    MasterAttributeDefinition.__table__,
    MasterProductPrice.__table__,
    MasterProductLocationAvailability.__table__,
    MasterProductOverride.__table__,
    MasterProductRelation.__table__,
    ProductChannelAssignment.__table__,
    ProductChannelTaxonomyAssignment.__table__,
    MasterCatalogIntentRun.__table__,
    MasterLocationRegistry.__table__,
    MasterTaxonomyNode.__table__,
    MasterTaxonomyChannelLink.__table__,
    MasterTaxonomyPathAlias.__table__,
    CollectionLandingPage.__table__,
    CollectionSkuOverride.__table__,
    MasterProductCollectionMembership.__table__,
    ChannelListingPath.__table__,
    ChannelListingPathTarget.__table__,
    ChannelTaxonomyMapping.__table__,
    ChannelAttributeAlias.__table__,
    ListingIntersectionRule.__table__,
    ProductListingPathAssignment.__table__,
    MagentoConnection.__table__,
    ManualTaxonomyAssignment.__table__,
    ManualTaxonomyAssignmentCollection.__table__,
    ManualAttributeLockRule.__table__,
    ManualAttributeLockTarget.__table__,
    ManualAttributeVocabulary.__table__,
    ManualAttributeVocabularyValue.__table__,
    ShopifyConnection.__table__,
    ShopifyTaxonomyRegistry.__table__,
    ChannelSchedule.__table__,
    ChannelSkuPrefixMapping.__table__,
    ChannelSkuMapping.__table__,
    ChannelJob.__table__,
    MagentoCategoryRegistry.__table__,
    MagentoAttributeRegistry.__table__,
    MagentoAttributeOptionRegistry.__table__,
    ShopifyCollectionRegistry.__table__,
    ShopifyAttributeRegistry.__table__,
]


@pytest.fixture()
def catalog_intent_session() -> Session:
    engine = create_engine("sqlite:///:memory:")

    @event.listens_for(engine, "connect")
    def _sqlite_pragma(dbapi_connection, connection_record):
        cursor = dbapi_connection.cursor()
        cursor.execute("PRAGMA foreign_keys=ON")
        cursor.close()

    Base.metadata.create_all(engine, tables=_CATALOG_INTENT_TABLES)
    session = sessionmaker(bind=engine, expire_on_commit=False)()
    try:
        yield session
    finally:
        session.close()
        engine.dispose()
