# coding: utf-8

"""
    aind-metadata-service

     ## aind-metadata-service  Service to pull data from example backend.  

    The version of the OpenAPI document: 1.1.3
    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from aind_metadata_service_client.models.average_hit_rate import AverageHitRate
from aind_metadata_service_client.models.fov_coordinate_ap import FovCoordinateAp
from aind_metadata_service_client.models.fov_coordinate_ml import FovCoordinateMl
from aind_metadata_service_client.models.hit_rate_trials010 import HitRateTrials010
from aind_metadata_service_client.models.hit_rate_trials2040 import HitRateTrials2040
from aind_metadata_service_client.models.input_source import InputSource
from aind_metadata_service_client.models.job_settings_starting_lickport_position_inner import JobSettingsStartingLickportPositionInner
from aind_metadata_service_client.models.output_directory import OutputDirectory
from aind_metadata_service_client.models.total_hits import TotalHits
from aind_metadata_service_client.models.trial_num import TrialNum
from aind_metadata_service_client.models.user_settings_config_file import UserSettingsConfigFile
from typing import Optional, Set
from typing_extensions import Self

class JobSettings(BaseModel):
    """
    Data that needs to be input by user. Can be pulled from env vars with BERGAMO prefix or set explicitly.
    """ # noqa: E501
    job_settings_name: Optional[StrictStr] = None
    input_source: Optional[InputSource] = None
    output_directory: Optional[OutputDirectory] = None
    user_settings_config_file: Optional[UserSettingsConfigFile] = None
    experimenter_full_name: List[StrictStr]
    subject_id: StrictStr
    imaging_laser_wavelength: StrictInt
    fov_imaging_depth: StrictInt
    fov_targeted_structure: StrictStr
    notes: Optional[StrictStr]
    mouse_platform_name: Optional[StrictStr] = None
    active_mouse_platform: Optional[StrictBool] = None
    session_type: Optional[StrictStr] = None
    iacuc_protocol: Optional[StrictStr] = None
    rig_id: Optional[StrictStr] = None
    behavior_camera_names: Optional[List[StrictStr]] = None
    ch1_filter_names: Optional[List[StrictStr]] = None
    ch1_detector_name: Optional[StrictStr] = None
    ch1_daq_name: Optional[StrictStr] = None
    ch2_filter_names: Optional[List[StrictStr]] = None
    ch2_detector_name: Optional[StrictStr] = None
    ch2_daq_name: Optional[StrictStr] = None
    imaging_laser_name: Optional[StrictStr] = None
    photostim_laser_name: Optional[StrictStr] = None
    stimulus_device_names: Optional[List[StrictStr]] = None
    photostim_laser_wavelength: Optional[StrictInt] = None
    fov_coordinate_ml: Optional[FovCoordinateMl] = None
    fov_coordinate_ap: Optional[FovCoordinateAp] = None
    fov_reference: Optional[StrictStr] = None
    starting_lickport_position: Optional[List[JobSettingsStartingLickportPositionInner]] = None
    behavior_task_name: Optional[StrictStr] = None
    hit_rate_trials_0_10: Optional[HitRateTrials010] = None
    hit_rate_trials_20_40: Optional[HitRateTrials2040] = None
    total_hits: Optional[TotalHits] = None
    average_hit_rate: Optional[AverageHitRate] = None
    trial_num: Optional[TrialNum] = None
    timezone: Optional[StrictStr] = None
    additional_properties: Optional[Dict[str, Any]] = None
    __properties: ClassVar[List[str]] = ["job_settings_name", "input_source", "output_directory", "user_settings_config_file", "experimenter_full_name", "subject_id", "imaging_laser_wavelength", "fov_imaging_depth", "fov_targeted_structure", "notes", "mouse_platform_name", "active_mouse_platform", "session_type", "iacuc_protocol", "rig_id", "behavior_camera_names", "ch1_filter_names", "ch1_detector_name", "ch1_daq_name", "ch2_filter_names", "ch2_detector_name", "ch2_daq_name", "imaging_laser_name", "photostim_laser_name", "stimulus_device_names", "photostim_laser_wavelength", "fov_coordinate_ml", "fov_coordinate_ap", "fov_reference", "starting_lickport_position", "behavior_task_name", "hit_rate_trials_0_10", "hit_rate_trials_20_40", "total_hits", "average_hit_rate", "trial_num", "timezone", "additional_properties"]

    model_config = ConfigDict(
        populate_by_name=True,
        validate_assignment=True,
        protected_namespaces=(),
    )


    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.model_dump(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of JobSettings from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of input_source
        if self.input_source:
            _dict['input_source'] = self.input_source.to_dict()
        # override the default output from pydantic by calling `to_dict()` of output_directory
        if self.output_directory:
            _dict['output_directory'] = self.output_directory.to_dict()
        # override the default output from pydantic by calling `to_dict()` of user_settings_config_file
        if self.user_settings_config_file:
            _dict['user_settings_config_file'] = self.user_settings_config_file.to_dict()
        # override the default output from pydantic by calling `to_dict()` of fov_coordinate_ml
        if self.fov_coordinate_ml:
            _dict['fov_coordinate_ml'] = self.fov_coordinate_ml.to_dict()
        # override the default output from pydantic by calling `to_dict()` of fov_coordinate_ap
        if self.fov_coordinate_ap:
            _dict['fov_coordinate_ap'] = self.fov_coordinate_ap.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in starting_lickport_position (list)
        _items = []
        if self.starting_lickport_position:
            for _item_starting_lickport_position in self.starting_lickport_position:
                if _item_starting_lickport_position:
                    _items.append(_item_starting_lickport_position.to_dict())
            _dict['starting_lickport_position'] = _items
        # override the default output from pydantic by calling `to_dict()` of hit_rate_trials_0_10
        if self.hit_rate_trials_0_10:
            _dict['hit_rate_trials_0_10'] = self.hit_rate_trials_0_10.to_dict()
        # override the default output from pydantic by calling `to_dict()` of hit_rate_trials_20_40
        if self.hit_rate_trials_20_40:
            _dict['hit_rate_trials_20_40'] = self.hit_rate_trials_20_40.to_dict()
        # override the default output from pydantic by calling `to_dict()` of total_hits
        if self.total_hits:
            _dict['total_hits'] = self.total_hits.to_dict()
        # override the default output from pydantic by calling `to_dict()` of average_hit_rate
        if self.average_hit_rate:
            _dict['average_hit_rate'] = self.average_hit_rate.to_dict()
        # override the default output from pydantic by calling `to_dict()` of trial_num
        if self.trial_num:
            _dict['trial_num'] = self.trial_num.to_dict()
        # set to None if job_settings_name (nullable) is None
        # and model_fields_set contains the field
        if self.job_settings_name is None and "job_settings_name" in self.model_fields_set:
            _dict['job_settings_name'] = None

        # set to None if input_source (nullable) is None
        # and model_fields_set contains the field
        if self.input_source is None and "input_source" in self.model_fields_set:
            _dict['input_source'] = None

        # set to None if output_directory (nullable) is None
        # and model_fields_set contains the field
        if self.output_directory is None and "output_directory" in self.model_fields_set:
            _dict['output_directory'] = None

        # set to None if user_settings_config_file (nullable) is None
        # and model_fields_set contains the field
        if self.user_settings_config_file is None and "user_settings_config_file" in self.model_fields_set:
            _dict['user_settings_config_file'] = None

        # set to None if notes (nullable) is None
        # and model_fields_set contains the field
        if self.notes is None and "notes" in self.model_fields_set:
            _dict['notes'] = None

        # set to None if mouse_platform_name (nullable) is None
        # and model_fields_set contains the field
        if self.mouse_platform_name is None and "mouse_platform_name" in self.model_fields_set:
            _dict['mouse_platform_name'] = None

        # set to None if active_mouse_platform (nullable) is None
        # and model_fields_set contains the field
        if self.active_mouse_platform is None and "active_mouse_platform" in self.model_fields_set:
            _dict['active_mouse_platform'] = None

        # set to None if session_type (nullable) is None
        # and model_fields_set contains the field
        if self.session_type is None and "session_type" in self.model_fields_set:
            _dict['session_type'] = None

        # set to None if iacuc_protocol (nullable) is None
        # and model_fields_set contains the field
        if self.iacuc_protocol is None and "iacuc_protocol" in self.model_fields_set:
            _dict['iacuc_protocol'] = None

        # set to None if rig_id (nullable) is None
        # and model_fields_set contains the field
        if self.rig_id is None and "rig_id" in self.model_fields_set:
            _dict['rig_id'] = None

        # set to None if behavior_camera_names (nullable) is None
        # and model_fields_set contains the field
        if self.behavior_camera_names is None and "behavior_camera_names" in self.model_fields_set:
            _dict['behavior_camera_names'] = None

        # set to None if ch1_filter_names (nullable) is None
        # and model_fields_set contains the field
        if self.ch1_filter_names is None and "ch1_filter_names" in self.model_fields_set:
            _dict['ch1_filter_names'] = None

        # set to None if ch1_detector_name (nullable) is None
        # and model_fields_set contains the field
        if self.ch1_detector_name is None and "ch1_detector_name" in self.model_fields_set:
            _dict['ch1_detector_name'] = None

        # set to None if ch1_daq_name (nullable) is None
        # and model_fields_set contains the field
        if self.ch1_daq_name is None and "ch1_daq_name" in self.model_fields_set:
            _dict['ch1_daq_name'] = None

        # set to None if ch2_filter_names (nullable) is None
        # and model_fields_set contains the field
        if self.ch2_filter_names is None and "ch2_filter_names" in self.model_fields_set:
            _dict['ch2_filter_names'] = None

        # set to None if ch2_detector_name (nullable) is None
        # and model_fields_set contains the field
        if self.ch2_detector_name is None and "ch2_detector_name" in self.model_fields_set:
            _dict['ch2_detector_name'] = None

        # set to None if ch2_daq_name (nullable) is None
        # and model_fields_set contains the field
        if self.ch2_daq_name is None and "ch2_daq_name" in self.model_fields_set:
            _dict['ch2_daq_name'] = None

        # set to None if imaging_laser_name (nullable) is None
        # and model_fields_set contains the field
        if self.imaging_laser_name is None and "imaging_laser_name" in self.model_fields_set:
            _dict['imaging_laser_name'] = None

        # set to None if photostim_laser_name (nullable) is None
        # and model_fields_set contains the field
        if self.photostim_laser_name is None and "photostim_laser_name" in self.model_fields_set:
            _dict['photostim_laser_name'] = None

        # set to None if stimulus_device_names (nullable) is None
        # and model_fields_set contains the field
        if self.stimulus_device_names is None and "stimulus_device_names" in self.model_fields_set:
            _dict['stimulus_device_names'] = None

        # set to None if photostim_laser_wavelength (nullable) is None
        # and model_fields_set contains the field
        if self.photostim_laser_wavelength is None and "photostim_laser_wavelength" in self.model_fields_set:
            _dict['photostim_laser_wavelength'] = None

        # set to None if fov_coordinate_ml (nullable) is None
        # and model_fields_set contains the field
        if self.fov_coordinate_ml is None and "fov_coordinate_ml" in self.model_fields_set:
            _dict['fov_coordinate_ml'] = None

        # set to None if fov_coordinate_ap (nullable) is None
        # and model_fields_set contains the field
        if self.fov_coordinate_ap is None and "fov_coordinate_ap" in self.model_fields_set:
            _dict['fov_coordinate_ap'] = None

        # set to None if fov_reference (nullable) is None
        # and model_fields_set contains the field
        if self.fov_reference is None and "fov_reference" in self.model_fields_set:
            _dict['fov_reference'] = None

        # set to None if starting_lickport_position (nullable) is None
        # and model_fields_set contains the field
        if self.starting_lickport_position is None and "starting_lickport_position" in self.model_fields_set:
            _dict['starting_lickport_position'] = None

        # set to None if behavior_task_name (nullable) is None
        # and model_fields_set contains the field
        if self.behavior_task_name is None and "behavior_task_name" in self.model_fields_set:
            _dict['behavior_task_name'] = None

        # set to None if hit_rate_trials_0_10 (nullable) is None
        # and model_fields_set contains the field
        if self.hit_rate_trials_0_10 is None and "hit_rate_trials_0_10" in self.model_fields_set:
            _dict['hit_rate_trials_0_10'] = None

        # set to None if hit_rate_trials_20_40 (nullable) is None
        # and model_fields_set contains the field
        if self.hit_rate_trials_20_40 is None and "hit_rate_trials_20_40" in self.model_fields_set:
            _dict['hit_rate_trials_20_40'] = None

        # set to None if total_hits (nullable) is None
        # and model_fields_set contains the field
        if self.total_hits is None and "total_hits" in self.model_fields_set:
            _dict['total_hits'] = None

        # set to None if average_hit_rate (nullable) is None
        # and model_fields_set contains the field
        if self.average_hit_rate is None and "average_hit_rate" in self.model_fields_set:
            _dict['average_hit_rate'] = None

        # set to None if trial_num (nullable) is None
        # and model_fields_set contains the field
        if self.trial_num is None and "trial_num" in self.model_fields_set:
            _dict['trial_num'] = None

        # set to None if timezone (nullable) is None
        # and model_fields_set contains the field
        if self.timezone is None and "timezone" in self.model_fields_set:
            _dict['timezone'] = None

        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of JobSettings from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "job_settings_name": obj.get("job_settings_name"),
            "input_source": InputSource.from_dict(obj["input_source"]) if obj.get("input_source") is not None else None,
            "output_directory": OutputDirectory.from_dict(obj["output_directory"]) if obj.get("output_directory") is not None else None,
            "user_settings_config_file": UserSettingsConfigFile.from_dict(obj["user_settings_config_file"]) if obj.get("user_settings_config_file") is not None else None,
            "experimenter_full_name": obj.get("experimenter_full_name"),
            "subject_id": obj.get("subject_id"),
            "imaging_laser_wavelength": obj.get("imaging_laser_wavelength"),
            "fov_imaging_depth": obj.get("fov_imaging_depth"),
            "fov_targeted_structure": obj.get("fov_targeted_structure"),
            "notes": obj.get("notes"),
            "mouse_platform_name": obj.get("mouse_platform_name"),
            "active_mouse_platform": obj.get("active_mouse_platform"),
            "session_type": obj.get("session_type"),
            "iacuc_protocol": obj.get("iacuc_protocol"),
            "rig_id": obj.get("rig_id"),
            "behavior_camera_names": obj.get("behavior_camera_names"),
            "ch1_filter_names": obj.get("ch1_filter_names"),
            "ch1_detector_name": obj.get("ch1_detector_name"),
            "ch1_daq_name": obj.get("ch1_daq_name"),
            "ch2_filter_names": obj.get("ch2_filter_names"),
            "ch2_detector_name": obj.get("ch2_detector_name"),
            "ch2_daq_name": obj.get("ch2_daq_name"),
            "imaging_laser_name": obj.get("imaging_laser_name"),
            "photostim_laser_name": obj.get("photostim_laser_name"),
            "stimulus_device_names": obj.get("stimulus_device_names"),
            "photostim_laser_wavelength": obj.get("photostim_laser_wavelength"),
            "fov_coordinate_ml": FovCoordinateMl.from_dict(obj["fov_coordinate_ml"]) if obj.get("fov_coordinate_ml") is not None else None,
            "fov_coordinate_ap": FovCoordinateAp.from_dict(obj["fov_coordinate_ap"]) if obj.get("fov_coordinate_ap") is not None else None,
            "fov_reference": obj.get("fov_reference"),
            "starting_lickport_position": [JobSettingsStartingLickportPositionInner.from_dict(_item) for _item in obj["starting_lickport_position"]] if obj.get("starting_lickport_position") is not None else None,
            "behavior_task_name": obj.get("behavior_task_name"),
            "hit_rate_trials_0_10": HitRateTrials010.from_dict(obj["hit_rate_trials_0_10"]) if obj.get("hit_rate_trials_0_10") is not None else None,
            "hit_rate_trials_20_40": HitRateTrials2040.from_dict(obj["hit_rate_trials_20_40"]) if obj.get("hit_rate_trials_20_40") is not None else None,
            "total_hits": TotalHits.from_dict(obj["total_hits"]) if obj.get("total_hits") is not None else None,
            "average_hit_rate": AverageHitRate.from_dict(obj["average_hit_rate"]) if obj.get("average_hit_rate") is not None else None,
            "trial_num": TrialNum.from_dict(obj["trial_num"]) if obj.get("trial_num") is not None else None,
            "timezone": obj.get("timezone"),
            "additional_properties": obj.get("additional_properties")
        })
        return _obj


