# 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.0
    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, StrictBool, StrictInt
from typing import Any, ClassVar, Dict, List, Optional
from typing_extensions import Annotated
from orbital_transfer.models.thrust_arc_definition import ThrustArcDefinition
from typing import Optional, Set
from typing_extensions import Self

class CustomManeuveringStrategy(BaseModel):
    """
    A custom maneuvering strategy. Depending on the orbital elements changed in the  mission (semi-major axis, eccentricity, inclination, RAAN or argument of latitude), the user can change the number of thrust arcs (1 or 2),  their position, and the thrust pattern. 
    """ # noqa: E501
    number_of_rest_orbits: Optional[StrictInt] = Field(default=None, description="The number of rest orbits", alias="numberOfRestOrbits")
    number_of_thrust_orbits: Optional[StrictInt] = Field(default=None, description="The number of thrust orbits", alias="numberOfThrustOrbits")
    number_of_shift_orbits: Optional[StrictInt] = Field(default=None, description="The number of shift orbits", alias="numberOfShiftOrbits")
    thrust_arc: Optional[ThrustArcDefinition] = Field(default=None, alias="thrustArc")
    thrust_arcs_number: Optional[Annotated[int, Field(le=2, strict=True, ge=1)]] = Field(default=None, description="The number of thrust arcs", alias="thrustArcsNumber")
    stop_thrusting_during_eclipse: Optional[StrictBool] = Field(default=None, description="Indicates whether the spacecraft has to stop thrusting during eclipse", alias="stopThrustingDuringEclipse")
    dynamic_duty_cycle: Optional[StrictBool] = Field(default=None, description="Indicates whether the duty cycle is dynamic", alias="dynamicDutyCycle")
    __properties: ClassVar[List[str]] = ["numberOfRestOrbits", "numberOfThrustOrbits", "numberOfShiftOrbits", "thrustArc", "thrustArcsNumber", "stopThrustingDuringEclipse", "dynamicDutyCycle"]

    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 CustomManeuveringStrategy 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 thrust_arc
        if self.thrust_arc:
            _dict['thrustArc'] = self.thrust_arc.to_dict()
        return _dict

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

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

        _obj = cls.model_validate({
            "numberOfRestOrbits": obj.get("numberOfRestOrbits"),
            "numberOfThrustOrbits": obj.get("numberOfThrustOrbits"),
            "numberOfShiftOrbits": obj.get("numberOfShiftOrbits"),
            "thrustArc": ThrustArcDefinition.from_dict(obj["thrustArc"]) if obj.get("thrustArc") is not None else None,
            "thrustArcsNumber": obj.get("thrustArcsNumber"),
            "stopThrustingDuringEclipse": obj.get("stopThrustingDuringEclipse"),
            "dynamicDutyCycle": obj.get("dynamicDutyCycle")
        })
        return _obj


