from typing import Any
import app.native.wndb as api
from app.native.wndb.s36_wda_cal import *
import app.infra.epanet as epanet


############################################################
# ChangeSet
############################################################

API_ADD    = api.API_ADD
API_UPDATE = api.API_UPDATE
API_DELETE = api.API_DELETE

ChangeSet = api.ChangeSet


############################################################
# enum
############################################################

JUNCTION  = api.JUNCTION
RESERVOIR = api.RESERVOIR
TANK      = api.TANK
PIPE      = api.PIPE
PUMP      = api.PUMP
VALVE     = api.VALVE
PATTERN   = api.PATTERN
CURVE     = api.CURVE

OVERFLOW_YES = api.OVERFLOW_YES
OVERFLOW_NO  = api.OVERFLOW_NO

PIPE_STATUS_OPEN   = api.PIPE_STATUS_OPEN
PIPE_STATUS_CLOSED = api.PIPE_STATUS_CLOSED
PIPE_STATUS_CV     = api.PIPE_STATUS_CV

VALVES_TYPE_PRV = api.VALVES_TYPE_PRV
VALVES_TYPE_PSV = api.VALVES_TYPE_PSV
VALVES_TYPE_PBV = api.VALVES_TYPE_PBV
VALVES_TYPE_FCV = api.VALVES_TYPE_FCV
VALVES_TYPE_TCV = api.VALVES_TYPE_TCV
VALVES_TYPE_GPV = api.VALVES_TYPE_GPV

TAG_TYPE_NODE = api.TAG_TYPE_NODE
TAG_TYPE_LINK = api.TAG_TYPE_LINK

LINK_STATUS_OPEN   = api.LINK_STATUS_OPEN
LINK_STATUS_CLOSED = api.LINK_STATUS_CLOSED
LINK_STATUS_ACTIVE = api.LINK_STATUS_ACTIVE

CURVE_TYPE_PUMP       = api.CURVE_TYPE_PUMP
CURVE_TYPE_EFFICIENCY = api.CURVE_TYPE_EFFICIENCY
CURVE_TYPE_VOLUME     = api.CURVE_TYPE_VOLUME
CURVE_TYPE_HEADLOSS   = api.CURVE_TYPE_HEADLOSS

SOURCE_TYPE_CONCEN    = api.SOURCE_TYPE_CONCEN
SOURCE_TYPE_MASS      = api.SOURCE_TYPE_MASS
SOURCE_TYPE_FLOWPACED = api.SOURCE_TYPE_FLOWPACED
SOURCE_TYPE_SETPOINT  = api.SOURCE_TYPE_SETPOINT

MIXING_MODEL_MIXED = api.MIXING_MODEL_MIXED
MIXING_MODEL_2COMP = api.MIXING_MODEL_2COMP
MIXING_MODEL_FIFO  = api.MIXING_MODEL_FIFO
MIXING_MODEL_LIFO  = api.MIXING_MODEL_LIFO

TIME_STATISTIC_NONE     = api.TIME_STATISTIC_NONE
TIME_STATISTIC_AVERAGED = api.TIME_STATISTIC_AVERAGED
TIME_STATISTIC_MINIMUM  = api.TIME_STATISTIC_MINIMUM
TIME_STATISTIC_MAXIMUM  = api.TIME_STATISTIC_MAXIMUM
TIME_STATISTIC_RANGE    = api.TIME_STATISTIC_RANGE

OPTION_UNITS_CFS  = api.OPTION_UNITS_CFS
OPTION_UNITS_GPM  = api.OPTION_UNITS_GPM
OPTION_UNITS_MGD  = api.OPTION_UNITS_MGD
OPTION_UNITS_IMGD = api.OPTION_UNITS_IMGD
OPTION_UNITS_AFD  = api.OPTION_UNITS_AFD
OPTION_UNITS_LPS  = api.OPTION_UNITS_LPS
OPTION_UNITS_LPM  = api.OPTION_UNITS_LPM
OPTION_UNITS_MLD  = api.OPTION_UNITS_MLD
OPTION_UNITS_CMH  = api.OPTION_UNITS_CMH
OPTION_UNITS_CMD  = api.OPTION_UNITS_CMD

OPTION_PRESSURE_PSI    = api.OPTION_PRESSURE_PSI
OPTION_PRESSURE_KPA    = api.OPTION_PRESSURE_KPA
OPTION_PRESSURE_METERS = api.OPTION_PRESSURE_METERS

OPTION_HEADLOSS_HW = api.OPTION_HEADLOSS_HW
OPTION_HEADLOSS_DW = api.OPTION_HEADLOSS_DW
OPTION_HEADLOSS_CM = api.OPTION_HEADLOSS_CM

OPTION_UNBALANCED_STOP     = api.OPTION_UNBALANCED_STOP
OPTION_UNBALANCED_CONTINUE = api.OPTION_UNBALANCED_CONTINUE

OPTION_DEMAND_MODEL_DDA = api.OPTION_DEMAND_MODEL_DDA
OPTION_DEMAND_MODEL_PDA = api.OPTION_DEMAND_MODEL_PDA

OPTION_QUALITY_NONE     = api.OPTION_QUALITY_NONE
OPTION_QUALITY_CHEMICAL = api.OPTION_QUALITY_CHEMICAL
OPTION_QUALITY_AGE      = api.OPTION_QUALITY_AGE
OPTION_QUALITY_TRACE    = api.OPTION_QUALITY_TRACE

OPTION_V3_FLOW_UNITS_CFS  = api.OPTION_V3_FLOW_UNITS_CFS
OPTION_V3_FLOW_UNITS_GPM  = api.OPTION_V3_FLOW_UNITS_GPM
OPTION_V3_FLOW_UNITS_MGD  = api.OPTION_V3_FLOW_UNITS_MGD
OPTION_V3_FLOW_UNITS_IMGD = api.OPTION_V3_FLOW_UNITS_IMGD
OPTION_V3_FLOW_UNITS_AFD  = api.OPTION_V3_FLOW_UNITS_AFD
OPTION_V3_FLOW_UNITS_LPS  = api.OPTION_V3_FLOW_UNITS_LPS
OPTION_V3_FLOW_UNITS_LPM  = api.OPTION_V3_FLOW_UNITS_LPM
OPTION_V3_FLOW_UNITS_MLD  = api.OPTION_V3_FLOW_UNITS_MLD
OPTION_V3_FLOW_UNITS_CMH  = api.OPTION_V3_FLOW_UNITS_CMH
OPTION_V3_FLOW_UNITS_CMD  = api.OPTION_V3_FLOW_UNITS_CMD

OPTION_V3_PRESSURE_UNITS_PSI    = api.OPTION_V3_PRESSURE_UNITS_PSI
OPTION_V3_PRESSURE_UNITS_KPA    = api.OPTION_V3_PRESSURE_UNITS_KPA
OPTION_V3_PRESSURE_UNITS_METERS = api.OPTION_V3_PRESSURE_UNITS_METERS

OPTION_V3_HEADLOSS_MODEL_HW = api.OPTION_V3_HEADLOSS_MODEL_HW
OPTION_V3_HEADLOSS_MODEL_DW = api.OPTION_V3_HEADLOSS_MODEL_DW
OPTION_V3_HEADLOSS_MODEL_CM = api.OPTION_V3_HEADLOSS_MODEL_CM

OPTION_V3_STEP_SIZING_FULL       = api.OPTION_V3_STEP_SIZING_FULL
OPTION_V3_STEP_SIZING_RELAXATION = api.OPTION_V3_STEP_SIZING_RELAXATION
OPTION_V3_STEP_SIZING_LINESEARCH = api.OPTION_V3_STEP_SIZING_LINESEARCH

OPTION_V3_IF_UNBALANCED_STOP     = api.OPTION_V3_IF_UNBALANCED_STOP
OPTION_V3_IF_UNBALANCED_CONTINUE = api.OPTION_V3_IF_UNBALANCED_CONTINUE

OPTION_V3_DEMAND_MODEL_FIXED       = api.OPTION_V3_DEMAND_MODEL_FIXED
OPTION_V3_DEMAND_MODEL_CONSTRAINED = api.OPTION_V3_DEMAND_MODEL_CONSTRAINED
OPTION_V3_DEMAND_MODEL_POWER       = api.OPTION_V3_DEMAND_MODEL_POWER
OPTION_V3_DEMAND_MODEL_LOGISTIC    = api.OPTION_V3_DEMAND_MODEL_LOGISTIC

OPTION_V3_LEAKAGE_MODEL_NONE  = api.OPTION_V3_LEAKAGE_MODEL_NONE
OPTION_V3_LEAKAGE_MODEL_POWER = api.OPTION_V3_LEAKAGE_MODEL_POWER
OPTION_V3_LEAKAGE_MODEL_FAVAD = api.OPTION_V3_LEAKAGE_MODEL_FAVAD

OPTION_V3_QUALITY_MODEL_NONE     = api.OPTION_V3_QUALITY_MODEL_NONE
OPTION_V3_QUALITY_MODEL_CHEMICAL = api.OPTION_V3_QUALITY_MODEL_CHEMICAL
OPTION_V3_QUALITY_MODEL_AGE      = api.OPTION_V3_QUALITY_MODEL_AGE
OPTION_V3_QUALITY_MODEL_TRACE    = api.OPTION_V3_QUALITY_MODEL_TRACE

OPTION_V3_QUALITY_UNITS_HRS  = api.OPTION_V3_QUALITY_UNITS_HRS
OPTION_V3_QUALITY_UNITS_PCNT = api.OPTION_V3_QUALITY_UNITS_PCNT
OPTION_V3_QUALITY_UNITS_MGL  = api.OPTION_V3_QUALITY_UNITS_MGL
OPTION_V3_QUALITY_UNITS_UGL  = api.OPTION_V3_QUALITY_UNITS_UGL

SCADA_DEVICE_TYPE_PRESSURE = api.SCADA_DEVICE_TYPE_PRESSURE
SCADA_DEVICE_TYPE_DEMAND   = api.SCADA_DEVICE_TYPE_DEMAND
SCADA_DEVICE_TYPE_QUALITY  = api.SCADA_DEVICE_TYPE_QUALITY
SCADA_DEVICE_TYPE_LEVEL    = api.SCADA_DEVICE_TYPE_LEVEL
SCADA_DEVICE_TYPE_FLOW     = api.SCADA_DEVICE_TYPE_FLOW
SCADA_DEVICE_TYPE_UNKNOWN  = api.SCADA_DEVICE_TYPE_UNKNOWN


SCADA_MODEL_TYPE_JUNCTION  = api.SCADA_MODEL_TYPE_JUNCTION
SCADA_MODEL_TYPE_RESERVOIR = api.SCADA_MODEL_TYPE_RESERVOIR
SCADA_MODEL_TYPE_TANK      = api.SCADA_MODEL_TYPE_TANK
SCADA_MODEL_TYPE_PIPE      = api.SCADA_MODEL_TYPE_PIPE
SCADA_MODEL_TYPE_PUMP      = api.SCADA_MODEL_TYPE_PUMP
SCADA_MODEL_TYPE_VALVE     = api.SCADA_MODEL_TYPE_VALVE


SCADA_ELEMENT_STATUS_ONLINE  = api.SCADA_ELEMENT_STATUS_ONLINE
SCADA_ELEMENT_STATUS_OFFLINE = api.SCADA_ELEMENT_STATUS_OFFLINE


PARTITION_TYPE_RB   = api.PARTITION_TYPE_RB
PARTITION_TYPE_KWAY = api.PARTITION_TYPE_KWAY


############################################################
# project
############################################################

def list_project() -> list[str]:
    return api.list_project()

def have_project(name: str) -> bool:
    return api.have_project(name)

def create_project(name: str) -> None:
    return api.create_project(name)

def delete_project(name: str) -> None:
    return api.delete_project(name)

def clean_project(excluded: list[str] = []) -> None:
    return api.clean_project(excluded)

def is_project_open(name: str) -> bool:
    return api.is_project_open(name)

def open_project(name: str) -> None:
    return api.open_project(name)

def close_project(name: str) -> None:
    return api.close_project(name)

def copy_project(source: str, new: str) -> None:
    return api.copy_project(source, new)

def read_inp(name: str, inp: str, version: str = '3') -> bool:
    return api.read_inp(name, inp, version)

def dump_inp(name: str, inp: str, version: str = '3') -> None:
    return api.dump_inp(name, inp, version)

def import_inp(name: str, cs: ChangeSet, version: str = '3') -> bool:
    return api.import_inp(name, cs, version)

def export_inp(name: str, version: str = '3') -> ChangeSet:
    return api.export_inp(name, version)

#DingZQ, 2025-02-04, 返回dict[str, Any]
def run_project_return_dict(name: str) -> dict[str, Any]:
    return epanet.run_project_return_dict(name, True)

# original code
def run_project(name: str) -> str:
    return epanet.run_project(name)

# put in inp folder, name without extension
def run_inp(name: str) -> str:
    return epanet.run_inp(name)

# path is absolute path
def dump_output(path: str) -> str:
    return epanet.dump_output(path)

#DingZQ, 2024-12-28, convert inp v3 to v2
def convert_inp_v3_to_v2(inp: str) -> ChangeSet:
    return api.convert_inp_v3_to_v2(inp)    

############################################################
# operation
############################################################

def get_current_operation(name: str) -> int:
    return api.get_current_operation(name)

def execute_undo(name: str, discard: bool = False) -> ChangeSet:
    return api.execute_undo(name, discard)

def execute_redo(name: str) -> ChangeSet:
    return api.execute_redo(name)

def list_snapshot(name: str) -> list[tuple[int, str]]:
    return api.list_snapshot(name)

def have_snapshot(name: str, tag: str) -> bool:
    return api.have_snapshot(name, tag)

def have_snapshot_for_operation(name: str, operation: int) -> bool:
    return api.have_snapshot_for_operation(name, operation)

def have_snapshot_for_current_operation(name: str) -> bool:
    return api.have_snapshot_for_current_operation(name)

def take_snapshot_for_operation(name: str, operation: int, tag: str) -> None:
    return api.take_snapshot_for_operation(name, operation, tag)

def take_snapshot_for_current_operation(name: str, tag: str) -> None:
    return api.take_snapshot_for_current_operation(name, tag)

# deprecated ! use take_snapshot_for_current_operation instead
def take_snapshot(name: str, tag: str) -> None:
    return api.take_snapshot(name, tag)

def update_snapshot(name: str, operation: int, tag: str) -> None:
    return api.update_snapshot(name, operation, tag)

def update_snapshot_for_current_operation(name: str, tag: str) -> None:
    return api.update_snapshot_for_current_operation(name, tag)

def delete_snapshot(name: str, tag: str) -> None:
    return api.delete_snapshot(name, tag)

def delete_snapshot_by_operation(name: str, operation: int) -> None:
    return api.delete_snapshot_by_operation(name, operation)

def get_operation_by_snapshot(name: str, tag: str) -> int | None:
    return api.get_operation_by_snapshot(name, tag)

def get_snapshot_by_operation(name: str, operation: int) -> str | None:
    return api.get_snapshot_by_operation(name, operation)

def pick_snapshot(name: str, tag: str, discard: bool = False) -> ChangeSet:
    return api.pick_snapshot(name, tag, discard)

def pick_operation(name: str, operation: int, discard: bool = False) -> ChangeSet:
    return api.pick_operation(name, operation, discard)

def sync_with_server(name: str, operation: int) -> ChangeSet:
    return api.sync_with_server(name, operation)

# combine commands as one undo/redo unit
def execute_batch_command(name: str, cs: ChangeSet) -> ChangeSet:
    return api.execute_batch_command(name, cs)

# execute command one by one
def execute_batch_commands(name: str, cs: ChangeSet) -> ChangeSet:
    return api.execute_batch_commands(name, cs)

def get_restore_operation(name: str) -> int:
    return api.get_restore_operation(name)

def set_restore_operation(name: str, operation: int) -> None:
    return api.set_restore_operation(name, operation)

def set_restore_operation_to_current(name: str) -> None:
    return api.set_restore_operation_to_current(name)

def restore(name: str, discard: bool = False) -> ChangeSet:
    return api.restore(name, discard)

def read(name: str, sql: str):
    return api.read(name, sql)

def try_read(name: str, sql: str):
    return api.try_read(name, sql)

def read_all(name: str, sql: str):
    return api.read_all(name, sql)

def write(name: str, sql: str):
    return api.write(name, sql)


############################################################
# extension_data
############################################################

def get_all_extension_data_keys(name: str) -> list[str]:
    return api.get_all_extension_data_keys(name)

def get_all_extension_data(name: str) -> dict[str, Any]:
    return api.get_all_extension_data(name)

def get_extension_data(name: str, key: str) -> str | None:
    return api.get_extension_data(name, key)

def set_extension_data(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_extension_data(name, cs)


############################################################
# type
############################################################

def is_node(name: str, node_id: str) -> bool:
    return api.is_node(name, node_id)

def is_junction(name: str, node_id: str) -> bool:
    return api.is_junction(name, node_id)

def is_reservoir(name: str, node_id: str) -> bool:
    return api.is_reservoir(name, node_id)

def is_tank(name: str, node_id: str) -> bool:
    return api.is_tank(name, node_id)

def is_link(name: str, link_id: str) -> bool:
    return api.is_link(name, link_id)

def is_pipe(name: str, link_id: str) -> bool:
    return api.is_pipe(name, link_id)

def is_pump(name: str, link_id: str) -> bool:
    return api.is_pump(name, link_id)

def is_valve(name: str, link_id: str) -> bool:
    return api.is_valve(name, link_id)

def is_curve(name: str, curve_id: str) -> bool:
    return api.is_curve(name, curve_id)

def is_pattern(name: str, pattern_id: str) -> bool:
    return api.is_pattern(name, pattern_id)

# DingZQ, 2025-02-05
def get_node_type(name: str, node_id: str) -> str:
    return api.get_node_type(name, node_id)

def get_link_type(name: str, link_id: str) -> str:
    return api.get_link_type(name, link_id)

def get_element_type(name: str, element_id: str) -> str:
    return api.get_element_type(name, element_id)

def get_element_type_value(name: str, element_id: str) -> int:
    return api.get_element_type_value(name, element_id)

def get_nodes(name: str) -> list[str]:
    return api.get_nodes(name)

def get_links(name: str) -> list[str]:
    return api.get_links(name)

def get_curves(name: str) -> list[str]:
    return api.get_curves(name)

def get_patterns(name: str) -> list[str]:
    return api.get_patterns(name)

def get_node_links(name: str, node_id: str) -> list[str]:
    return api.get_node_links(name, node_id)

# DingZQ, 2025-02-05
def get_node_properties(name: str, node_id: str) -> dict[str, Any]:
    if api.is_junction(name, node_id):
        return api.get_junction(name, node_id)
    elif api.is_reservoir(name, node_id):
        return api.get_reservoir(name, node_id)
    elif api.is_tank(name, node_id):
        return api.get_tank(name, node_id)

def get_link_properties(name: str, link_id: str) -> dict[str, Any]:
    if api.is_pipe(name, link_id):
        return api.get_pipe(name, link_id)
    elif api.is_pump(name, link_id):
        return api.get_pump(name, link_id)
    elif api.is_valve(name, link_id):
        return api.get_valve(name, link_id)

# type can be 'node' or 'link'
def get_element_properties_with_type(name: str, type: str, element_id: str) -> dict[str, Any]:
    if type == 'node':
        return get_node_properties(name, element_id)
    elif type == 'link':
        return get_link_properties(name, element_id)
    elif type == 'scada':
        return get_scada_info(name, element_id)
    else:
        return {}
   
# DingZQ, 2025-02-05
# element_id can be 'node' 'link' 'scada'
def get_element_properties(name: str, element_id: str) -> dict[str, Any]:
    if api.is_node(name, element_id):
        return get_node_properties(name, element_id)
    elif api.is_link(name, element_id):
        return get_link_properties(name, element_id)
    else:
        # return get_scada_element(name, element_id)
        return get_scada_info(name, element_id)
    
############################################################
# title 1.[TITLE]
############################################################

def get_title_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_title_schema(name)

def get_title(name: str) -> dict[str, Any]:
    return api.get_title(name)

def set_title(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_title(name, cs)


############################################################
# junction 2.[JUNCTIONS]
############################################################

def get_junction_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_junction_schema(name)

def get_junction(name: str, id: str) -> dict[str, Any]:
    return api.get_junction(name, id)

# DingZQ, 2025-03-29
def get_all_junctions(name: str) -> list[dict[str, Any]]:
    return api.get_all_junctions(name)

def set_junction(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_junction(name, cs)

# example: add_junction(p, ChangeSet({'id': 'j0', 'x': 0.0, 'y': 10.0, 'elevation': 20.0}))
def add_junction(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_junction(name, cs)

def delete_junction(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_junction_cascade(name, cs)


############################################################
# reservoir 3.[RESERVOIRS]
############################################################

def get_reservoir_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_reservoir_schema(name)

def get_reservoir(name: str, id: str) -> dict[str, Any]:
    return api.get_reservoir(name, id)

# DingZQ, 2025-03-29
def get_all_reservoirs(name: str) -> list[dict[str, Any]]:
    return api.get_all_reservoirs(name)

def set_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_reservoir(name, cs)

# example: add_reservoir(p, ChangeSet({'id': 'r0', 'x': 0.0, 'y': 10.0, 'head': 20.0}))
def add_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_reservoir(name, cs)

def delete_reservoir(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_reservoir_cascade(name, cs)


############################################################
# tank 4.[TANKS]
############################################################

def get_tank_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_tank_schema(name)

def get_tank(name: str, id: str) -> dict[str, Any]:
    return api.get_tank(name, id)

# DingZQ, 2025-03-29
def get_all_tanks(name: str) -> list[dict[str, Any]]:
    return api.get_all_tanks(name)

def set_tank(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_tank(name, cs)

# example: add_tank(p, ChangeSet({'id': 't0', 'x': 0.0, 'y': 10.0, 'elevation': 20.0, 'init_level': 1.0, 'min_level': 0.0, 'max_level': 2.0, 'diameter': 10.0, 'min_vol': 100.0}))
def add_tank(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_tank(name, cs)

def delete_tank(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_tank_cascade(name, cs)


############################################################
# pipe 5.[PIPES]
############################################################

def get_pipe_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_pipe_schema(name)

def get_pipe(name: str, id: str) -> dict[str, Any]:
    return api.get_pipe(name, id)

# DingZQ, 2025-03-29
def get_all_pipes(name: str) -> list[dict[str, Any]]:
    return api.get_all_pipes(name)

def set_pipe(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_pipe(name, cs)

# example: add_pipe(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'length': 100.0, 'diameter': 10.0, 'roughness': 0.1, 'minor_loss': 0.5, 'status': PIPE_STATUS_OPEN }))
def add_pipe(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_pipe(name, cs)

def delete_pipe(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_pipe_cascade(name, cs)


############################################################
# pump 6.[PUMPS]
############################################################

def get_pump_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_pump_schema(name)

def get_pump(name: str, id: str) -> dict[str, Any]:
    return api.get_pump(name, id)

# DingZQ, 2025-03-29
def get_all_pumps(name: str) -> list[dict[str, Any]]:
    return api.get_all_pumps(name)

def set_pump(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_pump(name, cs)

# example: add_pump(p, ChangeSet({'id': 'p0', 'node1': 'j1', 'node2': 'j2', 'power': 0}))
def add_pump(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_pump(name, cs)

def delete_pump(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_pump_cascade(name, cs)


############################################################
# valve 7.[VALVES]
############################################################

def get_valve_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_valve_schema(name)

def get_valve(name: str, id: str) -> dict[str, Any]:
    return api.get_valve(name, id)

# DingZQ, 2025-03-29
def get_all_valves(name: str) -> list[dict[str, Any]]:
    return api.get_all_valves(name)

def set_valve(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_valve(name, cs)

# example: add_valve(p, ChangeSet({'id': 'v0', 'node1': 'j1', 'node2': 'j2', 'diameter': 10.0, 'v_type': VALVES_TYPE_FCV, 'setting': 0.1, 'minor_loss': 0.5 }))
def add_valve(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_valve(name, cs)

def delete_valve(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_valve_cascade(name, cs)


############################################################
# tag 8.[TAGS]
############################################################

def get_tag_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_tag_schema(name)

def get_tags(name: str) -> list[dict[str, Any]]:
    return api.get_tags(name)

def get_tag(name: str, t_type: str, id: str) -> dict[str, Any]:
    return api.get_tag(name, t_type, id)

# example:
# set_tag(p, ChangeSet({'t_type': TAG_TYPE_NODE, 'id': 'j1', 'tag': 'j1t' }))
# set_tag(p, ChangeSet({'t_type': TAG_TYPE_LINK, 'id': 'p0', 'tag': 'p0t' }))
def set_tag(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_tag(name, cs)


############################################################
# demand 9.[DEMANDS]
############################################################

def get_demand_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_demand_schema(name)

def get_demand(name: str, junction: str) -> dict[str, Any]:
    return api.get_demand(name, junction)

# example: set_demand(p, ChangeSet({'junction': 'j1', 'demands': [{'demand': 10.0, 'pattern': None, 'category': 'x'}, {'demand': 20.0, 'pattern': None, 'category': None}]}))
def set_demand(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_demand(name, cs)


############################################################
# status 10.[STATUS]
############################################################

def get_status_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_status_schema(name)

def get_status(name: str, link: str) -> dict[str, Any]:
    return api.get_status(name, link)

# example: set_status(p, ChangeSet({'link': 'p0', 'status': LINK_STATUS_OPEN, 'setting': 10.0}))
def set_status(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_status(name, cs)


############################################################
# pattern 11.[PATTERNS]
############################################################

def get_pattern_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_pattern_schema(name)

def get_pattern(name: str, id: str) -> dict[str, Any]:
    return api.get_pattern(name, id)

def set_pattern(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_pattern(name, cs)

# example: add_pattern(p, ChangeSet({'id' : 'p0', 'factors': [1.0, 2.0, 3.0]}))
def add_pattern(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_pattern(name, cs)

def delete_pattern(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_pattern_cascade(name, cs)


############################################################
# curve 12.[CURVES]
############################################################

def get_curve_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_curve_schema(name)

def get_curve(name: str, id: str) -> dict[str, Any]:
    return api.get_curve(name, id)

def set_curve(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_curve(name, cs)

# example: add_curve(p, ChangeSet({'id' : 'c0', 'c_type' : CURVE_TYPE_PUMP, 'coords': [{'x': 1.0, 'y': 2.0}, {'x': 2.0, 'y': 1.0}]}))
def add_curve(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_curve(name, cs)

def delete_curve(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_curve_cascade(name, cs)


############################################################
# control 13.[CONTROLS]
############################################################

def get_control_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_control_schema(name)

def get_control(name: str) -> dict[str, Any]:
    return api.get_control(name)

# example: set_control(p, ChangeSet({'control': 'x'}))
def set_control(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_control(name, cs)


############################################################
# rule 14.[RULES]
############################################################

def get_rule_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_rule_schema(name)

def get_rule(name: str) -> dict[str, Any]:
    return api.get_rule(name)

# example: set_rule(p, ChangeSet({'rule': 'x'}))
def set_rule(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_rule(name, cs)


############################################################
# energy 15.[ENERGY]
############################################################

def get_energy_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_energy_schema(name)

def get_energy(name: str) -> dict[str, Any]:
    return api.get_energy(name)

def set_energy(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_energy(name, cs)

def get_pump_energy_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_pump_energy_schema(name)

def get_pump_energy(name: str, pump: str) -> dict[str, Any]:
    return api.get_pump_energy(name, pump)

def set_pump_energy(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_pump_energy(name, cs)


############################################################
# emitter 16.[EMITTERS]
############################################################

def get_emitter_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_emitter_schema(name)

def get_emitter(name: str, junction: str) -> dict[str, Any]:
    return api.get_emitter(name, junction)

# example: set_emitter(p, ChangeSet({'junction': 'j1', 'coefficient': 10.0}))
def set_emitter(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_emitter(name, cs)


############################################################
# quality 17.[QUALITY]
############################################################

def get_quality_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_quality_schema(name)

def get_quality(name: str, node: str) -> dict[str, Any]:
    return api.get_quality(name, node)

# example: set_quality(p, ChangeSet({'node': 'j1', 'quality': 10.0}))
def set_quality(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_quality(name, cs)


############################################################
# source 18.[SOURCES]
############################################################

def get_source_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_source_schema(name)

def get_source(name: str, node: str) -> dict[str, Any]:
    return api.get_source(name, node)

def set_source(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_source(name, cs)

# example: add_source(p, ChangeSet({'node': 'j0', 's_type': SOURCE_TYPE_CONCEN, 'strength': 10.0, 'pattern': 'p0'}))
def add_source(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_source(name, cs)

def delete_source(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_source(name, cs)


############################################################
# reaction 19.[REACTIONS]
############################################################

def get_reaction_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_reaction_schema(name)

def get_reaction(name: str) -> dict[str, Any]:
    return api.get_reaction(name)

def set_reaction(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_reaction(name, cs)

def get_pipe_reaction_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_pipe_reaction_schema(name)

def get_pipe_reaction(name: str, pipe: str) -> dict[str, Any]:
    return api.get_pipe_reaction(name, pipe)

def set_pipe_reaction(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_pipe_reaction(name, cs)

def get_tank_reaction_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_tank_reaction_schema(name)

def get_tank_reaction(name: str, tank: str) -> dict[str, Any]:
    return api.get_tank_reaction(name, tank)

def set_tank_reaction(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_tank_reaction(name, cs)


############################################################
# mixing 20.[MIXING]
############################################################

def get_mixing_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_mixing_schema(name)

def get_mixing(name: str, tank: str) -> dict[str, Any]:
    return api.get_mixing(name, tank)

def set_mixing(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_mixing(name, cs)

# example: add_mixing(p, ChangeSet({'tank': 't0', 'model': MIXING_MODEL_MIXED, 'value': 10.0}))
def add_mixing(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_mixing(name, cs)

def delete_mixing(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_mixing(name, cs)


############################################################
# time 21.[TIMES]
############################################################

def get_time_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_time_schema(name)

def get_time(name: str) -> dict[str, Any]:
    return api.get_time(name)

def set_time(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_time(name, cs)


############################################################
# report 22.[REPORT]
############################################################

# hardcode...


############################################################
# option 23.[OPTIONS]
############################################################

def get_option_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_option_schema(name)

def get_option(name: str) -> dict[str, Any]:
    return api.get_option(name)

def set_option(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_option_ex(name, cs)


############################################################
# option_v3 23.[EPA3][OPTIONS]
############################################################

def get_option_v3_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_option_v3_schema(name)

def get_option_v3(name: str) -> dict[str, Any]:
    return api.get_option_v3(name)

def set_option_v3(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_option_v3_ex(name, cs)


############################################################
# coord 24.[COORDINATES]
############################################################

def get_node_coord(name: str, node_id: str) -> dict[str, float]:
    return api.get_node_coord(name, node_id)

# DingZQ, 2024-12-08, get all node coord
# id, x, y, type
def get_network_node_coords(name: str) -> dict[str, dict[str, float]]:
    nodes_id_and_type = api.get_nodes_id_and_type(name)
    result = {}
    for node_id, node_type in nodes_id_and_type.items():
        coord = api.get_node_coord(name, node_id)
        coord['type'] = node_type
        result[node_id] = coord
    return result

# DingZQ 2024-12-31
# id, x, y, type
def get_major_node_coords(name: str, diameter: int) -> dict[str, dict[str, float]]:
    nodes_id_and_type = api.get_nodes_id_and_type(name)
    major_node_ids = api.get_major_nodes(name, diameter)
    result = {}
    for node_id in major_node_ids:
        coord = api.get_node_coord(name, node_id)
        coord['type'] = nodes_id_and_type[node_id]
        result[node_id] = coord
    return result

def get_network_in_extent(name: str, x1: float, y1: float, x2: float, y2: float) -> dict[str, Any]:
    pass
    


# DingZQ, 2024-12-08, get all links' start and end node
# link_id:link_type:node_id1:node_id2
def get_network_link_nodes(name: str) -> list[str]:
    links_id_and_type = api.get_links_id_and_type(name)
    result = []
    for link_id, link_type in links_id_and_type.items():
        nodes = api.get_link_nodes(name, link_id)
        result.append(f"{link_id}:{link_type}:{nodes[0]}:{nodes[1]}")
    return result

# DingZQ 2024-12-31
# link_id:pipe:node_id1:node_id2
def get_major_pipe_nodes(name: str, diameter: int) -> list[str]:
    major_pipe_ids = api.get_major_pipes(name, diameter)
    result = []
    for link_id in major_pipe_ids:
        nodes = api.get_link_nodes(name, link_id)
        result.append(f"{link_id}:pipe:{nodes[0]}:{nodes[1]}")
    return result

############################################################
# vertex 25.[VERTICES]
############################################################

def get_vertex_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_vertex_schema(name)

def get_vertex(name: str, link: str) -> dict[str, Any]:
    return api.get_vertex(name, link)

def set_vertex(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_vertex(name, cs)

def add_vertex(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_vertex(name, cs)

def delete_vertex(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_vertex(name, cs)

def get_all_vertex_links(name: str) -> list[str]:
    return api.get_all_vertex_links(name)

def get_all_vertices(name: str) -> list[dict[str, Any]]:
    return api.get_all_vertices(name)


############################################################
# label 26.[LABELS]
############################################################

def get_label_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_label_schema(name)

def get_label(name: str, x: float, y: float) -> dict[str, Any]:
    return api.get_label(name, x, y)

def set_label(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_label(name, cs)

def add_label(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_label(name, cs)

def delete_label(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_label(name, cs)


############################################################
# backdrop 27.[BACKDROP]
############################################################

def get_backdrop_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_backdrop_schema(name)

def get_backdrop(name: str) -> dict[str, Any]:
    return api.get_backdrop(name)

def set_backdrop(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_backdrop(name, cs)


############################################################
# end 28.[END]
############################################################


############################################################
# scada_device 29
############################################################

def get_scada_device_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_scada_device_schema(name)

def get_scada_device(name: str, id: str) -> dict[str, Any]:
    return api.get_scada_device(name, id)

def set_scada_device(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_scada_device(name, cs)

def add_scada_device(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_scada_device(name, cs)

def delete_scada_device(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_scada_device(name, cs)

def clean_scada_device(name: str) -> ChangeSet:
    return api.clean_scada_device(name)

def get_all_scada_device_ids(name: str) -> list[str]:
    return api.get_all_scada_device_ids(name)

def get_all_scada_devices(name: str) -> list[dict[str, Any]]:
    return api.get_all_scada_devices(name)


############################################################
# scada_device_data 30
############################################################

def get_scada_device_data_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_scada_device_data_schema(name)

def get_scada_device_data(name: str, device_id: str) -> dict[str, Any]:
    return api.get_scada_device_data(name, device_id)

# example: set_scada_device_data(p, ChangeSet({'device_id': 'sm_device', 'data': [{ 'time': '2023-02-10 00:02:22', 'value': 100.0 }, { 'time': '2023-02-10 00:03:22', 'value': 200.0 }]}))
# time format must be 'YYYY-MM-DD HH:MM:SS'
def set_scada_device_data(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_scada_device_data(name, cs)

# example: add_scada_device_data(p, ChangeSet({'device_id': 'sm_device', 'time': '2023-02-10 00:02:22', 'value': 100.0}))
def add_scada_device_data(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_scada_device_data(name, cs)

# example: delete_scada_device_data(p, ChangeSet({'device_id': 'sm_device', 'time': '2023-02-12 00:02:22'}))
def delete_scada_device_data(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_scada_device_data(name, cs)

def clean_scada_device_data(name: str) -> ChangeSet:
    return api.clean_scada_device_data(name)


############################################################
# scada_element 31
############################################################

def get_scada_element_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_scada_element_schema(name)

def get_scada_element(name: str, id: str) -> dict[str, Any]:
    return api.get_scada_element(name, id)

def set_scada_element(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_scada_element(name, cs)

def add_scada_element(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_scada_element(name, cs)

def delete_scada_element(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_scada_element(name, cs)

def clean_scada_element(name: str) -> ChangeSet:
    return api.clean_scada_element(name)

def get_all_scada_element_ids(name: str) -> list[str]:
    return api.get_all_scada_element_ids(name)

def get_all_scada_elements(name: str) -> list[dict[str, Any]]:
    return api.get_all_scada_elements(name)


############################################################
# general_region 32
############################################################

def get_nodes_in_boundary(name: str, boundary: list[tuple[float, float]]) -> list[str]:
    return api.get_nodes_in_boundary(name, boundary)

def get_nodes_in_region(name: str, region_id: str) -> list[str]:
    return api.get_nodes_in_region(name, region_id)

def get_links_on_region_boundary(name: str, region_id: str) -> list[str]:
    return api.get_links_on_region_boundary(name, region_id)

def calculate_convex_hull(name: str, nodes: list[str]) -> list[tuple[float, float]]:
    return api.calculate_convex_hull(name, nodes)

def calculate_boundary(name: str, nodes: list[str]) -> list[tuple[float, float]]:
    return api.calculate_boundary(name, nodes)

def inflate_boundary(name: str, boundary: list[tuple[float, float]], delta: float = 0.5) -> list[tuple[float, float]]:
    return api.inflate_boundary(name, boundary, delta)

def inflate_region(name: str, region_id: str, delta: float = 0.5) -> list[tuple[float, float]]:
    return api.inflate_region(name, region_id, delta)

def get_region_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_region_schema(name)

def get_region(name: str, id: str) -> dict[str, Any]:
    return api.get_region(name, id)

def set_region(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_region(name, cs)

# example: add_region(p, ChangeSet({'id': 'r', 'boundary': [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 0.0)]}))
def add_region(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_region(name, cs)

def delete_region(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_region(name, cs)


############################################################
# district_metering_area 33
############################################################

def calculate_district_metering_area_for_nodes(name: str, nodes: list[str], part_count: int = 1, part_type: int = PARTITION_TYPE_RB) -> list[list[str]]:
    return api.calculate_district_metering_area_for_nodes(name, nodes, part_count, part_type)

def calculate_district_metering_area_for_region(name: str, region: str, part_count: int = 1, part_type: int = PARTITION_TYPE_RB) -> list[list[str]]:
    return api.calculate_district_metering_area_for_region(name, region, part_count, part_type)

def calculate_district_metering_area_for_network(name: str, part_count: int = 1, part_type: int = PARTITION_TYPE_RB) -> list[list[str]]:
    return api.calculate_district_metering_area_for_network(name, part_count, part_type)

def get_district_metering_area_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_district_metering_area_schema(name)

def get_district_metering_area(name: str, id: str) -> dict[str, Any]:
    return api.get_district_metering_area(name, id)

def set_district_metering_area(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_district_metering_area(name, cs)

def add_district_metering_area(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_district_metering_area(name, cs)

def delete_district_metering_area(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_district_metering_area(name, cs)

def get_all_district_metering_area_ids(name: str) -> list[str]:
    return api.get_all_district_metering_area_ids(name)

def get_all_district_metering_areas(name: str) -> list[dict[str, Any]]:
    return api.get_all_district_metering_areas(name)

def generate_district_metering_area(name: str, part_count: int = 1, part_type: int = PARTITION_TYPE_RB, inflate_delta: float = 0.5) -> ChangeSet:
    return api.generate_district_metering_area(name, part_count, part_type, inflate_delta)

def generate_sub_district_metering_area(name: str, dma: str, part_count: int = 1, part_type: int = PARTITION_TYPE_RB, inflate_delta: float = 0.5) -> ChangeSet:
    return api.generate_sub_district_metering_area(name, dma, part_count, part_type, inflate_delta)


############################################################
# service_area 34
############################################################

def calculate_service_area(name: str) -> list[dict[str, list[str]]]:
    return api.calculate_service_area(name)

def get_service_area_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_service_area_schema(name)

def get_service_area(name: str, id: str) -> dict[str, Any]:
    return api.get_service_area(name, id)

def set_service_area(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_service_area(name, cs)

def add_service_area(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_service_area(name, cs)

def delete_service_area(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_service_area(name, cs)

def get_all_service_area_ids(name: str) -> list[str]:
    return api.get_all_service_area_ids(name)

def get_all_service_areas(name: str) -> list[dict[str, Any]]:
    return api.get_all_service_areas(name)

def generate_service_area(name: str, inflate_delta: float = 0.5) -> ChangeSet:
    return api.generate_service_area(name, inflate_delta)


############################################################
# virtual_district 35
############################################################

def calculate_virtual_district(name: str, centers: list[str]) -> dict[str, list[Any]]:
    return api.calculate_virtual_district(name, centers)

def get_virtual_district_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_virtual_district_schema(name)

def get_virtual_district(name: str, id: str) -> dict[str, Any]:
    return api.get_virtual_district(name, id)

def set_virtual_district(name: str, cs: ChangeSet) -> ChangeSet:
    return api.set_virtual_district(name, cs)

def add_virtual_district(name: str, cs: ChangeSet) -> ChangeSet:
    return api.add_virtual_district(name, cs)

def delete_virtual_district(name: str, cs: ChangeSet) -> ChangeSet:
    return api.delete_virtual_district(name, cs)

def get_all_virtual_district_ids(name: str) -> list[str]:
    return api.get_all_virtual_district_ids(name)

def get_all_virtual_districts(name: str) -> list[dict[str, Any]]:
    return api.get_all_virtual_districts(name)

def generate_virtual_district(name: str, centers: list[str], inflate_delta: float = 0.5) -> ChangeSet:
    return api.generate_virtual_district(name, centers, inflate_delta)


############################################################
# water_distribution_area 36
############################################################

def calculate_demand_to_nodes(name: str, demand: float, nodes: list[str]) -> dict[str, float]:
    return api.calculate_demand_to_nodes(name, demand, nodes)

# if region is general or wda => get_nodes_in_boundary
# if region is dma, sa or vd  => get stored nodes in table
# TODO: more test
def calculate_demand_to_region(name: str, demand: float, region: str) -> dict[str, float]:
    return api.calculate_demand_to_region(name, demand, region)

def calculate_demand_to_network(name: str, demand: float) -> dict[str, float]:
    return api.calculate_demand_to_network(name, demand)


############################################################
# scada_info 38 | WMH
############################################################

def get_scada_info_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_scada_info_schema(name)

def get_scada_info(name: str, id: str) -> dict[str, Any]:
    return api.get_scada_info(name, id)


def get_all_scada_info(name: str) -> list[dict[str, Any]]:
    return api.get_all_scada_info(name)

# DingZQ 2025-03-27
############################################################
# 39 users
############################################################
def get_user_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_user_schema(name)

def get_user(name: str, user_name: str) -> dict[str, Any]:
    return api.get_user(name, user_name=user_name)

def get_all_users(name: str) -> list[dict[str, Any]]:
    return api.get_all_users(name)

############################################################
# scheme 40
############################################################
def get_scheme_schema(name: str) -> dict[str, dict[str, Any]]:
    return api.get_scheme_schema(name)

def get_scheme(name: str, schema_name: str) -> dict[str, Any]:
    return api.get_scheme(name, schema_name)

def get_all_schemes(name: str) -> list[dict[str, Any]]:
    return api.get_all_schemes(name)

############################################################
# pipe_risk_probability 41
############################################################
def get_pipe_risk_probability_now(name: str, pipe_id: str) -> dict[str, Any]:
    return api.get_pipe_risk_probability_now(name, pipe_id)

def get_pipe_risk_probability(name: str, pipe_id: str) -> dict[str, Any]:
    return api.get_pipe_risk_probability(name, pipe_id)

def get_pipes_risk_probability(name: str, pipe_ids: list[str]) -> list[dict[str, Any]]:
    return api.get_pipes_risk_probability(name, pipe_ids)

def get_network_pipe_risk_probability_now(name: str) -> list[dict[str, Any]]:
    return api.get_network_pipe_risk_probability_now(name)

def get_pipe_risk_probability_geometries(name: str) -> dict[str, Any]:
    return api.get_pipe_risk_probability_geometries(name)

############################################################
# sensor_placement 42
############################################################
def get_all_sensor_placements(name: str) -> list[dict[Any, Any]]:
    return api.get_all_sensor_placements(name)

############################################################
# burst_locate_result 43
############################################################
def get_all_burst_locate_results(name: str) -> list[dict[Any, Any]]:
    return api.get_all_burst_locate_results(name)



