from typing import Any, Dict, List, Optional, Tuple, Union

from com.inductiveautomation.ignition.common import BasicDataset, Dataset
from com.inductiveautomation.ignition.common.model.values import (
    QualifiedValue,
    QualityCode,
)
from com.inductiveautomation.ignition.common.opc import BrowseElementType
from com.inductiveautomation.ignition.common.script.abc import AbstractJythonSequence
from com.inductiveautomation.ignition.common.script.message import Request
from dev.coatl.helper.types import AnyStr
from java.io import OutputStream, Writer
from java.lang import Class
from java.lang import Exception as JavaException
from java.lang import Object
from java.util import Locale
from org.json import JSONObject
from org.python.core import PyFunction, PyList, PyObject, PySequence
from org.slf4j import Logger

class AbstractOPCUtilities(Object):
    def browseServer(
        self, opcServer: AnyStr, nodeId: AnyStr
    ) -> List[AbstractOPCUtilities.PyOPCTag]: ...
    def getServers(self, *args: PyObject, **kwargs: AnyStr) -> List[AnyStr]: ...
    def getServerState(self, opcServer: AnyStr) -> AnyStr: ...
    def isServerEnabled(self, serverName: AnyStr) -> bool: ...
    def readValue(self, opcServer: AnyStr, itemPath: AnyStr) -> QualifiedValue: ...
    def readValues(
        self, opcServer: AnyStr, itemPaths: List[AnyStr]
    ) -> QualifiedValue: ...
    def setServerEnabled(self, serverName: AnyStr, enabled: bool) -> None: ...
    def writeValue(self, *args: PyObject, **kwargs: AnyStr) -> QualityCode: ...
    def writeValues(self, *args: PyObject, **kwargs: AnyStr) -> List[QualityCode]: ...

    class PyOPCTag(PyObject):
        displayName: AnyStr
        elementType: BrowseElementType
        nodeId: AnyStr
        serverName: AnyStr
        def __init__(
            self,
            serverName: AnyStr,
            nodeId: AnyStr,
            displayName: AnyStr,
            elementType: BrowseElementType,
        ) -> None: ...
        def __findattr_ex__(self, name: AnyStr) -> PyObject: ...
        def getDisplayName(self) -> AnyStr: ...
        def getElementType(self) -> BrowseElementType: ...
        def getNodeId(self) -> AnyStr: ...
        def getServerName(self) -> AnyStr: ...

class DatasetUtilities(Object):
    @staticmethod
    def addColumn(ds: Dataset, *args: Any) -> Dataset: ...
    @staticmethod
    def addRow(ds: Dataset, *args: Any) -> Dataset: ...
    @staticmethod
    def addRows(ds: Dataset, *args: Any) -> Dataset: ...
    @staticmethod
    def appendDataset(ds1: Dataset, ds2: Dataset) -> Dataset: ...
    @staticmethod
    def clearDataset(ds: Dataset) -> Dataset: ...
    @staticmethod
    def dataSetToExcel(headerRow: bool, datasets: List[Object]) -> AnyStr: ...
    @staticmethod
    def dataSetToExcelBytes(
        headerRow: bool,
        objects: List[Object],
        nullsEmpty: bool,
        sheetNames: List[AnyStr],
    ) -> bytearray: ...
    @staticmethod
    def dataSetToExcelStreaming(
        headerRow: bool, objects: List[Object], out: OutputStream, nullsEmpty: bool
    ) -> None: ...
    @staticmethod
    def dataSetToHTML(headerRow: bool, ds: Dataset, title: AnyStr) -> AnyStr: ...
    @staticmethod
    def dataSetToHTMLStreaming(
        headerRow: bool, ds: Dataset, title: AnyStr, fw: Writer
    ) -> None: ...
    @staticmethod
    def deleteRow(ds: Dataset, row: int) -> Dataset: ...
    @staticmethod
    def deleteRows(ds: Dataset, rows: List[int]) -> Dataset: ...
    @staticmethod
    def filterColumns(dataset: Dataset, columns: PySequence) -> Dataset: ...
    @staticmethod
    def formatDates(
        dataset: Dataset, format: AnyStr, locale: Locale = ...
    ) -> Dataset: ...
    @staticmethod
    def fromCSV(csv: AnyStr) -> Dataset: ...
    @staticmethod
    def fromCSVJava(csv: AnyStr) -> Dataset: ...
    @staticmethod
    def getColumnHeaders(ds: Dataset) -> PyList: ...
    @staticmethod
    def insertColumn(ds: Dataset, *args: Any) -> Dataset: ...
    @staticmethod
    def insertRow(ds: Dataset, *args: Any) -> Dataset: ...
    @staticmethod
    def setValue(
        ds: Dataset, row: int, col: Union[int, AnyStr], value: Union[Object, PyObject]
    ) -> Dataset: ...
    @staticmethod
    def sort(
        ds: Dataset,
        keyColumn: Union[int, AnyStr],
        ascending: Optional[bool] = ...,
        naturalOrdering: Optional[bool] = ...,
    ) -> BasicDataset: ...
    @staticmethod
    def toCSV(*args: PyObject, **kwargs: AnyStr) -> AnyStr: ...
    @staticmethod
    def toCSVJava(
        ds: Dataset, showHeaders: bool, forExport: bool, localized: bool = ...
    ) -> AnyStr: ...
    @staticmethod
    def toCSVJavaStreaming(
        ds: Dataset, showHeaders: bool, forExport: bool, sw: Writer, localized: bool
    ) -> None: ...
    @staticmethod
    def toDataSet(*args: Any) -> Dataset: ...
    @staticmethod
    def toExcel(*args: PyObject, **kwargs: AnyStr) -> bytearray: ...
    @staticmethod
    def toJSONObject(data: Dataset) -> JSONObject: ...
    @staticmethod
    def toPyDataSet(dataset: Dataset) -> PyDataSet: ...
    @staticmethod
    def updateRow(ds: Dataset, row: int, changes: Dict[AnyStr, Any]) -> Dataset: ...

    class PyDataSet(Dataset, AbstractJythonSequence):
        def __init__(self, ds: Optional[Dataset] = ...) -> None: ...
        def __add__(self, other: PyObject) -> PyObject: ...
        def getColumnCount(self) -> int: ...
        def getColumnIndex(self, colName: AnyStr) -> int: ...
        def getColumnName(self, col: int) -> AnyStr: ...
        def getColumnNames(self) -> List[AnyStr]: ...
        def getColumnType(self, col: int) -> Class: ...
        def getColumnTypes(self) -> List[Class]: ...
        def getPrimitiveValueAt(self, row: int, col: int) -> float: ...
        def getQualityAt(self, row: int, col: int) -> QualityCode: ...
        def getRowCount(self) -> int: ...
        def getValueAt(self, row: int, col: Union[int, AnyStr]) -> Any: ...
        def setData(self, data: Dataset) -> None: ...

class SProcCall(Object):
    callFinished: bool
    datasource: AnyStr
    params: Dict[SProcCall.SProcArgKey, SProcCall.SProcArg]
    procedureName: AnyStr
    resultset: Dataset
    returnParam: SProcCall.SProcArg
    skipAudit: bool
    txId: AnyStr
    updateCount: int
    def getDataSource(self) -> AnyStr: ...
    def getOutParamValue(self, param: Union[int, AnyStr]) -> Any: ...
    def getProcedureName(self) -> AnyStr: ...
    def getResultSet(self) -> BasicDataset: ...
    def getReturnValue(self) -> Any: ...
    def getTxId(self) -> AnyStr: ...
    def getUpdateCount(self) -> int: ...
    def isSkipAudit(self) -> bool: ...
    def registerInParam(
        self, param: Union[int, AnyStr], typeCode: int, value: Any
    ) -> None: ...
    def registerOutParam(self, param: Union[int, AnyStr], typeCode: int) -> None: ...
    def registerReturnParam(self, typeCode: int) -> None: ...
    def setSkipAudit(self, skipAudit: bool) -> None: ...
    def setTxId(self, txId: AnyStr) -> None: ...

    class SProcArg(Object):
        outParam: bool
        inParam: bool
        paramType: int
        value: Object
        def getParamType(self) -> int: ...
        def getValue(self) -> Any: ...
        def isInParam(self) -> bool: ...
        def isOutParam(self) -> bool: ...
        def setParamType(self, paramType: int) -> None: ...
        def setValue(self, value: Object) -> None: ...

    class SProcArgKey(Object):
        index: int
        name: AnyStr
        def getParamIndex(self) -> int: ...
        def getParamName(self) -> AnyStr: ...
        def isNamedParam(self) -> bool: ...

class SystemUtilities(Object):
    @staticmethod
    def logger(loggerName: AnyStr) -> Logger: ...
    @staticmethod
    def parseTranslateArguments(
        *args: PyObject, **kwargs: AnyStr
    ) -> Tuple[AnyStr, AnyStr, bool]: ...

    class RequestImpl(Object, Request):
        timeout: int
        def __init__(self, timeout: int) -> None: ...
        def cancel(self) -> None: ...
        def checkTimeout(self) -> None: ...
        def finishExceptionally(self, e: JavaException) -> None: ...
        def finishSuccessfully(self, value: Object) -> None: ...
        def get(self) -> Object: ...
        def getError(self) -> JavaException: ...
        def getLongId(self) -> long: ...
        def onError(self, func: PyFunction) -> None: ...
        def onSuccess(self, func: PyFunction) -> None: ...
