from sqlalchemy import inspect
from marshmallow import pre_load, post_dump, fields, EXCLUDE
from flask import g
from .models import (
    TDatasets,
    TAcquisitionFramework,
    CorAcquisitionFrameworkActor,
    CorDatasetActor,
    TBibliographicReference,
)
from geonature.utils.env import MA
from geonature.utils.schema import CruvedSchemaMixin
from geonature.core.gn_commons.models import TModules
from geonature.core.gn_commons.schemas import ModuleSchema
# Note: import of SourceSchema is importent as it trigger import of synthese models
# which define TDatasets.sources & TDatasets.synthese_records_count, and these must be
# defined before AutoSchema creation to be known by marshmallow!
from geonature.core.gn_synthese.schemas import SourceSchema
from geonature.core.gn_permissions.tools import get_scopes_by_action
from utils_flask_sqla.schema import SmartRelationshipsMixin
from pypnusershub.schemas import UserSchema, OrganismeSchema
from pypnnomenclature.schemas import NomenclatureSchema
[docs]
class DatasetActorSchema(SmartRelationshipsMixin, MA.SQLAlchemyAutoSchema):
[docs]
    role = MA.Nested(UserSchema, dump_only=True) 
[docs]
    nomenclature_actor_role = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    organism = MA.Nested(OrganismeSchema, dump_only=True) 
    @pre_load
[docs]
    def make_dataset_actor(self, data, **kwargs):
        if data.get("id_cda") is None:
            data.pop("id_cda", None)
        return data 
 
[docs]
class DatasetSchema(CruvedSchemaMixin, SmartRelationshipsMixin, MA.SQLAlchemyAutoSchema):
[docs]
    __module_code__ = "METADATA" 
[docs]
    cor_dataset_actor = MA.Nested(DatasetActorSchema, many=True, unknown=EXCLUDE) 
[docs]
    modules = MA.Nested(
        ModuleSchema, many=True, exclude=("meta_create_date", "meta_update_date"), unknown=EXCLUDE
    ) 
[docs]
    creator = MA.Nested(UserSchema, dump_only=True) 
[docs]
    nomenclature_data_type = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    nomenclature_dataset_objectif = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    nomenclature_collecting_method = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    nomenclature_data_origin = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    nomenclature_source_status = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    nomenclature_resource_type = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    cor_territories = MA.Nested(NomenclatureSchema, many=True, unknown=EXCLUDE) 
[docs]
    acquisition_framework = MA.Nested("AcquisitionFrameworkSchema", dump_only=True) 
[docs]
    sources = MA.Nested(SourceSchema, many=True, dump_only=True) 
    @post_dump(pass_many=False, pass_original=True)
    # retro-compatibility with mobile app
    @post_dump(pass_many=True, pass_original=True)
[docs]
    def mobile_app_compat(self, data, original, many, **kwargs):
        if self.context.get("mobile_app"):
            if many:
                for ds, orig_ds in zip(data, original):
                    ds["meta_create_date"] = str(orig_ds.meta_create_date)
                data = {"data": data}
            else:
                data["meta_create_date"] = str(original.meta_create_date)
        return data 
 
[docs]
class BibliographicReferenceSchema(SmartRelationshipsMixin, MA.SQLAlchemyAutoSchema):
[docs]
    acquisition_framework = MA.Nested("AcquisitionFrameworkSchema", dump_only=True) 
    @pre_load
[docs]
    def make_biblio_ref(self, data, **kwargs):
        if data.get("id_bibliographic_reference") is None:
            data.pop("id_bibliographic_reference", None)
        return data 
 
[docs]
class AcquisitionFrameworkActorSchema(SmartRelationshipsMixin, MA.SQLAlchemyAutoSchema):
[docs]
    role = MA.Nested(UserSchema, dump_only=True) 
[docs]
    nomenclature_actor_role = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    organism = MA.Nested(OrganismeSchema, dump_only=True) 
[docs]
    cor_volets_sinp = MA.Nested(OrganismeSchema, dump_only=True) 
    @pre_load
[docs]
    def make_af_actor(self, data, **kwargs):
        if data.get("id_cafa") is None:
            data.pop("id_cafa", None)
        return data 
 
[docs]
class AcquisitionFrameworkSchema(
    CruvedSchemaMixin, SmartRelationshipsMixin, MA.SQLAlchemyAutoSchema
):
[docs]
    __module_code__ = "METADATA" 
[docs]
    t_datasets = MA.Nested(DatasetSchema, many=True) 
[docs]
    datasets = MA.Nested(DatasetSchema, many=True) 
[docs]
    bibliographical_references = MA.Nested(BibliographicReferenceSchema, many=True) 
[docs]
    cor_af_actor = MA.Nested(AcquisitionFrameworkActorSchema, many=True, unknown=EXCLUDE) 
[docs]
    cor_volets_sinp = MA.Nested(NomenclatureSchema, many=True, unknown=EXCLUDE) 
[docs]
    cor_objectifs = MA.Nested(NomenclatureSchema, many=True, unknown=EXCLUDE) 
[docs]
    cor_territories = MA.Nested(NomenclatureSchema, many=True, unknown=EXCLUDE) 
[docs]
    nomenclature_territorial_level = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    nomenclature_financing_type = MA.Nested(NomenclatureSchema, dump_only=True) 
[docs]
    creator = MA.Nested(UserSchema, dump_only=True)