"""
This type stub file was generated by cyright.
"""

from enum import Enum
from typing import Any, Dict, List, Optional, Tuple
from cpython.datetime import datetime

class UnitSystem(Enum):
    """
    Enumeration of the unit system used in the output file.

    :ivar US: US customary units.
    :type US: int
    :ivar SI: SI metric units.
    :type SI: int
    """
    US = ...
    SI = ...


class FlowUnits(Enum):
    """
    Enumeration of the flow units used in the simulation.

    :ivar CFS: Cubic feet per second.
    :type CFS: int
    :ivar GPM: Gallons per minute.
    :type GPM: int
    :ivar MGD: Million gallons per day.
    :type MGD: int
    :ivar CMS: Cubic meters per second.
    :type CMS: int
    :ivar LPS: Liters per second.
    :type LPS: int
    :ivar MLD: Million liters per day.
    :type MLD: int
    """
    CFS = ...
    GPM = ...
    MGD = ...
    CMS = ...
    LPS = ...
    MLD = ...


class ConcentrationUnits(Enum):
    """
    Enumeration of the concentration units used in the simulation.

    :ivar MG: Milligrams per liter.
    :type MG: int
    :ivar UG: Micrograms per liter.
    :type UG: int
    :ivar COUNT: Counts per liter.
    :type COUNT: int
    :ivar NONE: No units.
    :type NONE: int
    """
    MG = ...
    UG = ...
    COUNT = ...
    NONE = ...


class ElementType(Enum):
    """
    Enumeration of the SWMM element types.

    :ivar SUBCATCHMENT: Subcatchment.
    :type SUBCATCHMENT: int
    :ivar NODE: Node.
    :type NODE: int
    :ivar LINK: Link.
    :type LINK: int
    :ivar SYS: System.
    :type SYS: int
    :ivar POLLUTANT: Pollutant.
    :type POLLUTANT: int
    """
    SUBCATCHMENT = ...
    NODE = ...
    LINK = ...
    SYSTEM = ...
    POLLUTANT = ...


class TimeAttribute(Enum):
    """
    Enumeration of the report time related attributes.

    :ivar REPORT_STEP: Report step size (seconds).
    :type REPORT_STEP: int
    :ivar NUM_PERIODS: Number of reporting periods.
    :type NUM_PERIODS: int
    """
    REPORT_STEP = ...
    NUM_PERIODS = ...


class SubcatchAttribute(Enum):
    """
    Enumeration of the subcatchment attributes.

    :ivar RAINFALL: Subcatchment rainfall (in/hr or mm/hr).
    :type RAINFALL: int
    :ivar SNOW_DEPTH: Subcatchment snow depth (in or mm).
    :type SNOW_DEPTH: int
    :ivar EVAPORATION_LOSS: Subcatchment evaporation loss (in/hr or mm/hr).
    :type EVAPORATION_LOSS: int
    :ivar INFILTRATION_LOSS: Subcatchment infiltration loss (in/hr or mm/hr).
    :type INFILTRATION_LOSS: int
    :ivar RUNOFF_RATE: Subcatchment runoff flow (flow units).
    :type RUNOFF_RATE: int
    :ivar GROUNDWATER_OUTFLOW: Subcatchment groundwater flow (flow units).
    :type GROUNDWATER_OUTFLOW: int
    :ivar GW_TABLE: Subcatchment groundwater elevation (ft or m).
    :type GW_TABLE: int
    :ivar SOIL_MOISTURE: Subcatchment soil moisture content (-).
    :type SOIL_MOISTURE: int
    :ivar POLLUTANT_CONCENTRATION: Subcatchment pollutant concentration (-).
    :type POLLUTANT_CONCENTRATION: int
    """
    RAINFALL = ...
    SNOW_DEPTH = ...
    EVAPORATION_LOSS = ...
    INFILTRATION_LOSS = ...
    RUNOFF_RATE = ...
    GROUNDWATER_OUTFLOW = ...
    GROUNDWATER_TABLE_ELEVATION = ...
    SOIL_MOISTURE = ...
    POLLUTANT_CONCENTRATION = ...


class NodeAttribute(Enum):
    """
    Enumeration of the node attributes.

    :ivar INVERT_DEPTH: Node depth above invert (ft or m).
    :type INVERT_DEPTH: int
    :ivar HYDRAULIC_HEAD: Node hydraulic head (ft or m).
    :type HYDRAULIC_HEAD: int
    :ivar STORED_VOLUME: Node volume stored (ft3 or m3).
    :type STORED_VOLUME: int
    :ivar LATERAL_INFLOW: Node lateral inflow (flow units).
    :type LATERAL_INFLOW: int
    :ivar TOTAL_INFLOW: Node total inflow (flow units).
    :type TOTAL_INFLOW: int
    :ivar FLOODING_LOSSES: Node flooding losses (flow units).
    :type FLOODING_LOSSES: int
    :ivar POLLUTANT_CONCENTRATION: Node pollutant concentration (-).
    :type POLLUTANT_CONCENTRATION: int
    """
    INVERT_DEPTH = ...
    HYDRAULIC_HEAD = ...
    STORED_VOLUME = ...
    LATERAL_INFLOW = ...
    TOTAL_INFLOW = ...
    FLOODING_LOSSES = ...
    POLLUTANT_CONCENTRATION = ...


class LinkAttribute(Enum):
    """
    Enumeration of the link attributes.

    :ivar FLOW_RATE: Link flow rate (flow units).
    :type FLOW_RATE: int
    :ivar FLOW_DEPTH: Link flow depth (ft or m).
    :type FLOW_DEPTH: int
    :ivar FLOW_VELOCITY: Link flow velocity (ft/s or m/s).
    :type FLOW_VELOCITY: int
    :ivar FLOW_VOLUME: Link flow volume (ft3 or m3).
    :type FLOW_VOLUME: int
    :ivar CAPACITY: Link capacity (fraction of conduit filled).
    :type CAPACITY: int
    :ivar POLLUTANT_CONCENTRATION: Link pollutant concentration (-).
    :type POLLUTANT_CONCENTRATION: int
    """
    FLOW_RATE = ...
    FLOW_DEPTH = ...
    FLOW_VELOCITY = ...
    FLOW_VOLUME = ...
    CAPACITY = ...
    POLLUTANT_CONCENTRATION = ...


class SystemAttribute(Enum):
    """
    Enumeration of the system attributes.

    :ivar AIR_TEMP: Air temperature (deg. F or deg. C).
    :type AIR_TEMP: int
    :ivar RAINFALL: Rainfall intensity (in/hr or mm/hr).
    :type RAINFALL: int
    :ivar SNOW_DEPTH: Snow depth (in or mm).
    :type SNOW_DEPTH: int
    :ivar EVAP_INFIL_LOSS: Evaporation and infiltration loss rate (in/day or mm/day).
    :type EVAP_INFIL_LOSS: int
    :ivar RUNOFF_FLOW: Runoff flow (flow units).
    :type RUNOFF_FLOW: int
    :ivar DRY_WEATHER_INFLOW: Dry weather inflow (flow units).
    :type DRY_WEATHER_INFLOW: int
    :ivar GROUNDWATER_INFLOW: Groundwater inflow (flow units).
    :type GROUNDWATER_INFLOW: int
    :ivar RDII_INFLOW: Rainfall Derived Infiltration and Inflow (RDII) (flow units).
    :type RDII_INFLOW: int
    :ivar DIRECT_INFLOW: Direct inflow (flow units).
    :type DIRECT_INFLOW: int
    :ivar TOTAL_LATERAL_INFLOW: Total lateral inflow; sum of variables 4 to 8 (flow units).
    :type TOTAL_LATERAL_INFLOW: int
    :ivar FLOOD_LOSSES: Flooding losses (flow units).
    :type FLOOD_LOSSES: int
    :ivar OUTFALL_FLOWS: Outfall flow (flow units).
    :type OUTFALL_FLOWS: int
    :ivar VOLUME_STORED: Volume stored in storage nodes (ft3 or m3).
    :type VOLUME_STORED: int
    :ivar EVAPORATION_RATE: Evaporation rate (in/day or mm/day).
    :type EVAPORATION_RATE: int
    """
    AIR_TEMP = ...
    RAINFALL = ...
    SNOW_DEPTH = ...
    EVAP_INFIL_LOSS = ...
    RUNOFF_FLOW = ...
    DRY_WEATHER_INFLOW = ...
    GROUNDWATER_INFLOW = ...
    RDII_INFLOW = ...
    DIRECT_INFLOW = ...
    TOTAL_LATERAL_INFLOW = ...
    FLOOD_LOSSES = ...
    OUTFALL_FLOWS = ...
    VOLUME_STORED = ...
    EVAPORATION_RATE = ...


class SWMMOutputException(Exception):
    """
    Exception class for SWMM output file processing errors.
    """
    def __init__(self, message: str) -> None:
        """
        Constructor to initialize the exception message.

        :param message: Error message.
        :type message: str
        """
        ...
    


class Output:
    """
    Class to read and process the output file generated by the SWMM simulation.

    :cvar _output_file_handle: Handle to the SWMM output file.
    :cvar _version: Version of the SWMM output file.
    :cvar _units: Unit system used in the SWMM output file.
    :cvar _flow_units: Flow units used in the SWMM output file.
    :cvar _output_size: Size of the project in the SWMM output file.
    :cvar _pollutant_units: Pollutant units used in the SWMM output file.
    :cvar _start_date: Start date of the simulation in the SWMM output file.
    :cvar _report_step: Report step size in seconds.
    :cvar _num_periods: Number of reporting periods.
    :cvar _times: Times of the simulation in the SWMM output file.
    """

    def __init__(self, output_file: str) -> None:
        """
        Constructor to open the SWMM output file.

        :param output_file: Path to the SWMM output file.
        :type output_file: str
        """
        ...
    
    def __enter__(self): # -> Self@Output:
        """
        Method to return the SWMM output file instance.
        """
        ...
    
    def __exit__(self, exc_type, exc_value, traceback): # -> None:
        """
        Method to close the SWMM output file instance.
        """
        ...
    
    @property
    def version(self) -> int:
        """
        Method to get the version of the SWMM output file.

        :return: Version of the SWMM output file.
        :rtype: str
        """
        ...
    
    @property
    def output_size(self) -> Dict[str, int]:
        """
        Method to get the size of the project in the SWMM output file.

        :return: Size of the project in the SWMM output file.
        :rtype: int
        """
        ...
    
    @property
    def units(self) -> Tuple[UnitSystem, FlowUnits, Optional[List[ConcentrationUnits]]]:
        """
        Method to get the unit system used in the SWMM output file.

        :return: Tuple of the unit system, flow units, and pollutant units used in the SWMM output file.
        :rtype: Tuple[UnitSystem, FlowUnits, Optional[List[ConcentrationUnits]]]
        """
        ...
    
    @property
    def flow_units(self) -> FlowUnits:
        """
        Method to get the flow units used in the SWMM output file.

        :return: Flow units used in the SWMM output file.
        :rtype: FlowUnits
        """
        ...
    
    @property
    def pollutant_units(self) -> List[ConcentrationUnits]:
        """
        Method to get the pollutant units used in the SWMM output file.

        :return: Pollutant units used in the SWMM output file.
        :rtype: List[ConcentrationUnits]
        """
        ...
    
    @property
    def start_date(self) -> Any:
        """
        Method to get the start date of the simulation in the SWMM output file.

        :return: Start date of the simulation in the SWMM output file.
        :rtype: datetime
        """
        ...
    
    @property
    def times(self) -> List[datetime]:
        """
        Method to get the times of the simulation in the SWMM output file.

        :return: Times of the simulation in the SWMM output file.
        :rtype: List[datetime]
        """
        ...
    
    def get_time_attribute(self, time_attribute: TimeAttribute) -> int:
        """
        Method to get the temporal attributes of the simulation in the SWMM output file.

        :return: Temporal attributes of the simulation in the SWMM output file.
        :rtype: int
        """
        ...
    
    def get_element_name(self, element_type: ElementType, element_index: int) -> str:
        """
        Method to get the name of an element in the SWMM output file.

        :param element_type: Type of the element.
        :type element_type: int
        :param index: Index of the element.
        :type index: int
        :return: Name of the element.
        :rtype: str
        """
        ...
    
    def get_element_names(self, element_type: ElementType) -> List[str]:
        """
        Method to get the names of all elements of a given type in the SWMM output file.

        :param element_type: Type of the element.
        :type element_type: int
        :return: Names of all elements of the given type.
        :rtype: List[str]
        """
        ...
    
    def get_subcatchment_timeseries(self, element_index: int, attribute: SubcatchAttribute, start_date_index: int = ..., end_date_index: int = ...) -> Dict[datetime, float]:
        """
        Method to get the time series data for a subcatchment attribute in the SWMM output file.

        :param subcatchment_index: Index of the subcatchment.
        :type subcatchment_index: int
        :param attribute: Subcatchment attribute.
        :type attribute: SubcatchAttribute
        :param start_date_index: Start date index. Default is 0.
        :type start_date_index: int
        :param end_date_index: End date index. Default is the last date index.
        :type end_date_index: int        
        :return: Time series data for the subcatchment attribute.
        :rtype: Dict[datetime, double]
        TODO: Add option to return memoryview
        """
        ...
    
    def get_node_timeseries(self, element_index: int, attribute: NodeAttribute, start_date_index: int = ..., end_date_index: int = ...) -> Dict[datetime, float]:
        """
        Method to get the time series data for a node attribute in the SWMM output file.

        :param node_index: Index of the node.
        :type node_index: int
        :param attribute: Node attribute.
        :type attribute: NodeAttribute
        :param start_date_index: Start date index. Default is 0.
        :type start_date_index: int
        :param end_date_index: End date index. Default is the last date index.
        :type end_date_index: int
        :return: Time series data for the node attribute.
        :rtype: Dict[datetime, double]
        """
        ...
    
    def get_link_timeseries(self, element_index: int, attribute: LinkAttribute, start_date_index: int = ..., end_date_index: int = ...) -> Dict[datetime, float]:
        """
        Method to get the time series data for a link attribute in the SWMM output file.

        :param link_index: Index of the link.
        :type link_index: int
        :param attribute: Link attribute.
        :type attribute: LinkAttribute
        :param start_date_index: Start date index. Default is 0.
        :type start_date_index: int
        :param end_date_index: End date index. Default is the last date index.
        :type end_date_index: int
        :return: Time series data for the link attribute.
        :rtype: Dict[datetime, double]
        """
        ...
    
    def get_system_timeseries(self, attribute: SystemAttribute, start_date_index: int = ..., end_date_index: int = ...) -> Dict[datetime, float]:
        """
        Method to get the time series data for a system attribute in the SWMM output file.

        :param attribute: System attribute.
        :type attribute: SystemAttribute
        :param start_date_index: Start date index. Default is 0.
        :type start_date_index: int
        :param end_date_index: End date index. Default is the last date index.
        :type end_date_index: int
        :return: Time series data for the system attribute.
        :rtype: Dict[datetime, double]
        """
        ...
    
    def get_subcatchment_values_by_time_and_attribute(self, time_index: int, attribute: SubcatchAttribute) -> Dict[str, float]:
        """
        Method to get the subcatchment values for all subcatchments for a given time index and attribute.

        :param time_index: Time index.
        :type time_index: int
        :param attribute: Subcatchment attribute.
        :type attribute: SubcatchAttribute
        :return: Subcatchment values for all subcatchments. 
        :rtype: Dict[str, float]
        """
        ...
    
    def get_node_values_by_time_and_attribute(self, time_index: int, attribute: NodeAttribute) -> Dict[str, float]:
        """
        Method to get the node values for all nodes for a given time index and attribute.

        :param time_index: Time index.
        :type time_index: int
        :param attribute: Node attribute.
        :type attribute: NodeAttribute
        :return: Node values for all nodes.
        :rtype: Dict[str, float]
        """
        ...
    
    def get_link_values_by_time_and_attribute(self, time_index: int, attribute: LinkAttribute) -> Dict[str, float]:
        """
        Method to get the link values for all links for a given time index and attribute.

        :param time_index: Time index.
        :type time_index: int
        :param attribute: Link attribute.
        :type attribute: LinkAttribute
        :return: Link values for all links.
        :rtype: Dict[str, float]
        """
        ...
    
    def get_system_values_by_time_and_attribute(self, time_index: int, attribute: SystemAttribute) -> Dict[str, float]:
        """
        Method to get the system values for a given time index and attribute.
        
        :param time_index: Time index.
        :type time_index: int
        :param attribute: System attribute.
        :type attribute: SystemAttribute
        :return: System values.
        :rtype: Dict[str, float]
        """
        ...
    
    def get_subcatchment_values_by_time_and_element_index(self, time_index: int, element_index: int) -> Dict[str, float]:
        """
        Method to get all attributes of a given subcatchment for specified time.

        :param time_index: Time index.
        :type time_index: int
        :param subcatchment_index: Index of the subcatchment.
        :type subcatchment_index: int
        :return: Dictionary of subcatchment attributes.
        :rtype: Dict[str, float]
        """
        ...
    
    def get_node_values_by_time_and_element_index(self, time_index: int, element_index: int) -> Dict[str, float]:
        """
        Method to get all attributes of a given node for specified time.

        :param time_index: Time index.
        :type time_index: int
        :param node_index: Index of the node.
        :type node_index: int
        :return: Dictionary of node attributes.
        :rtype: Dict[str, float]
        """
        ...
    
    def get_link_values_by_time_and_element_index(self, time_index: int, element_index: int) -> Dict[str, float]:
        """
        Method to get all attributes of a given link for specified time.

        :param time_index: Time index.
        :type time_index: int
        :param link_index: Index of the link.
        :type link_index: int

        :return: Dictionary of link attributes.
        :rtype: Dict[str, float]
        """
        ...
    
    def get_system_values_by_time(self, time_index: int) -> Dict[str, float]:
        """
        Method to get all attributes of the system for specified time.

        :param time_index: Time index.
        :type time_index: int

        :return: Dictionary of system attributes.
        :rtype: Dict[str, float]
        """
        ...
    


