# coding: utf-8

"""
    Orbital transfer API

    An orbital transfer corresponds to a non-coplanar orbit transfer where semi-major axis, inclination and eccentricity can be simultaneously changed.  When considering a change in inclination, an efficiency factor is taken into account to consider the fact that this maneuver is  less efficient away from the orbital nodes. The length of the thrust arcs about the nodes is dictated by the duty cycle.   Different perturbations can be considered while performing this manoeuvre: Earth potential, third-body (Sun, Moon), atmospheric drag  and solar radiation pressure.   <b>CHANGELOG</b> <ul>   <li><b>2.2.0</b> - 2024-07-11 - Add space weather data source choice to <b>NRLMSISE00AtmosphericModel</b> schema</li>   <li><b>2.1.0</b> - 2024-07-03 - Add <b>atmosphericModel</b> in <b>DragPerturbation</b> schema</li>   <li><b>2.0.0</b> - 2024-06-06 - Complete refactoring of the API</li> </ul> 

    The version of the OpenAPI document: 2.2.2
    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, Field, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from orbital_transfer.models.analytical_orbital_transfer_request_drag_perturbation import AnalyticalOrbitalTransferRequestDragPerturbation
from orbital_transfer.models.orbit import Orbit
from orbital_transfer.models.platform import Platform
from orbital_transfer.models.propulsion_system import PropulsionSystem
from orbital_transfer.models.spacecraft_geometry import SpacecraftGeometry
from typing import Optional, Set
from typing_extensions import Self

class AnalyticalOrbitalTransferRequest(BaseModel):
    """
    AnalyticalOrbitalTransferRequest
    """ # noqa: E501
    mission_date_time: Optional[StrictStr] = Field(default=None, description="The mission date and time.   This is the date and time at which the mission starts. ", alias="missionDateTime")
    maximum_duration: Optional[StrictInt] = Field(default=None, description="The simulation maximum duration (in days).  This is the maximum duration expected for the mission. If the target is not reached after that duration,  the mission would fail. This parameter is used to avoid unpredicted long simulation. ", alias="maximumDuration")
    initial_orbit: Orbit = Field(alias="initialOrbit")
    target_orbit: Optional[Orbit] = Field(default=None, alias="targetOrbit")
    spacecraft_geometry: Optional[SpacecraftGeometry] = Field(default=None, alias="spacecraftGeometry")
    platform: Optional[Platform] = None
    propulsion_system: Optional[PropulsionSystem] = Field(default=None, alias="propulsionSystem")
    drag_perturbation: Optional[AnalyticalOrbitalTransferRequestDragPerturbation] = Field(default=None, alias="dragPerturbation")
    __properties: ClassVar[List[str]] = ["missionDateTime", "maximumDuration", "initialOrbit", "targetOrbit", "spacecraftGeometry", "platform", "propulsionSystem", "dragPerturbation"]

    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 AnalyticalOrbitalTransferRequest 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 initial_orbit
        if self.initial_orbit:
            _dict['initialOrbit'] = self.initial_orbit.to_dict()
        # override the default output from pydantic by calling `to_dict()` of target_orbit
        if self.target_orbit:
            _dict['targetOrbit'] = self.target_orbit.to_dict()
        # override the default output from pydantic by calling `to_dict()` of spacecraft_geometry
        if self.spacecraft_geometry:
            _dict['spacecraftGeometry'] = self.spacecraft_geometry.to_dict()
        # override the default output from pydantic by calling `to_dict()` of platform
        if self.platform:
            _dict['platform'] = self.platform.to_dict()
        # override the default output from pydantic by calling `to_dict()` of propulsion_system
        if self.propulsion_system:
            _dict['propulsionSystem'] = self.propulsion_system.to_dict()
        # override the default output from pydantic by calling `to_dict()` of drag_perturbation
        if self.drag_perturbation:
            _dict['dragPerturbation'] = self.drag_perturbation.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "missionDateTime": obj.get("missionDateTime"),
            "maximumDuration": obj.get("maximumDuration"),
            "initialOrbit": Orbit.from_dict(obj["initialOrbit"]) if obj.get("initialOrbit") is not None else None,
            "targetOrbit": Orbit.from_dict(obj["targetOrbit"]) if obj.get("targetOrbit") is not None else None,
            "spacecraftGeometry": SpacecraftGeometry.from_dict(obj["spacecraftGeometry"]) if obj.get("spacecraftGeometry") is not None else None,
            "platform": Platform.from_dict(obj["platform"]) if obj.get("platform") is not None else None,
            "propulsionSystem": PropulsionSystem.from_dict(obj["propulsionSystem"]) if obj.get("propulsionSystem") is not None else None,
            "dragPerturbation": AnalyticalOrbitalTransferRequestDragPerturbation.from_dict(obj["dragPerturbation"]) if obj.get("dragPerturbation") is not None else None
        })
        return _obj


