from typing import Any, Callable, ClassVar, Iterator, List, Tuple, Set, Sequence, Optional

from . import Path


class SourcePosition:
    line: int
    column: int


class SourceRange:
    start: SourcePosition
    end: SourcePosition


class SourceLocation:
    range: SourceRange

    def length(self) -> int: ...
    def view(self) -> str: ...


class SymbolKind:
    variable: ClassVar[SymbolKind] = ...
    function: ClassVar[SymbolKind] = ...
    type: ClassVar[SymbolKind] = ...
    param: ClassVar[SymbolKind] = ...
    field: ClassVar[SymbolKind] = ...


class Symbol:
    node: AstNode
    decl: Declaration
    comment: str
    type: str
    kind: SymbolKind
    provider: "Nss"
    view: str


class InlayHint:
    message: str
    position: SourcePosition


class Context:
    def __init__(self, include_paths: List[str] = [
    ], command_script: str = "nwscript") -> None: ...

    def add_include_path(self, path: str): ...

    def command_script(self) -> "Optional[Nss]": ...

    def get(self, resref: str,
            is_command_script: bool = False) -> "Optional[Nss]": ...


class DiagnosticType:
    __members__: ClassVar[dict] = ...  # read-only
    lexical: ClassVar[DiagnosticType] = ...
    parse: ClassVar[DiagnosticType] = ...
    semantic: ClassVar[DiagnosticType] = ...


class DiagnosticSeverity:
    __members__: ClassVar[dict] = ...  # read-only
    error: ClassVar[DiagnosticSeverity] = ...
    hint: ClassVar[DiagnosticSeverity] = ...
    information: ClassVar[DiagnosticSeverity] = ...
    warning: ClassVar[DiagnosticSeverity] = ...


class Diagnostic:
    type: DiagnosticType
    severity: DiagnosticSeverity
    script: str
    message: str
    location: SourceRange


class SignatureHelp:
    decl: FunctionDecl | FunctionDefinition
    expr: CallExpression
    active_param: int


class AssignExpression(Expression):
    @property
    def lhs(self) -> Expression: ...
    @property
    def operator(self) -> NssToken: ...
    @property
    def rhs(self) -> Expression: ...


class AstNode:
    def accept(self, arg0) -> None: ...
    def complete(self, needle: str) -> Sequence["Symbol"]: ...


class BinaryExpression(Expression):
    @property
    def lhs(self) -> Expression: ...
    @property
    def operator(self) -> NssToken: ...
    @property
    def rhs(self) -> Expression: ...


class BlockStatement(Statement):
    range: SourceRange
    def __getitem__(self, arg0: int) -> Statement: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator: ...


class CallExpression(Expression):
    def __getitem__(self, arg0: int) -> Expression: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator: ...
    @property
    def expr(self) -> Expression: ...


class ComparisonExpression(Expression):
    @property
    def lhs(self) -> Expression: ...
    @property
    def operator(self) -> NssToken: ...
    @property
    def rhs(self) -> Expression: ...


class ConditionalExpression(Expression):
    @property
    def false_branch(self) -> Expression: ...
    @property
    def test(self) -> Expression: ...
    @property
    def true_branch(self) -> Expression: ...


class Declaration(Statement):
    def identifier(self) -> str: ...
    @property
    def type(self) -> Type: ...


class DeclList(Declaration):
    def __getitem__(self, index: int) -> Declaration: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator: ...
    def locate_decl(self, name: str) -> Optional[Declaration]: ...


class DoStatement(Statement):
    @property
    def block(self) -> BlockStatement: ...
    @property
    def test(self) -> Expression: ...


class DotExpression(Expression):
    @property
    def lhs(self) -> Expression: ...
    @property
    def rhs(self) -> Expression: ...


class EmptyExpression(Expression):
    pass


class EmptyStatement(Statement):
    pass


class ExprStatement(Statement):
    @property
    def expr(self) -> Expression: ...


class Expression(AstNode):
    pass


class ForStatement(Statement):
    @property
    def block(self) -> Statement: ...
    @property
    def increment(self) -> Expression: ...
    @property
    def init(self) -> Expression: ...
    @property
    def test(self) -> Expression: ...


class FunctionDecl(Declaration):
    def __getitem__(self, arg0: int) -> Declaration: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator: ...


class FunctionDefinition(Declaration):
    @property
    def block(self) -> BlockStatement: ...
    @property
    def decl(self) -> FunctionDecl: ...


class GroupingExpression(Expression):
    @property
    def expr(self) -> Expression: ...


class IfStatement(Statement):
    @property
    def false_branch(self) -> Statement: ...
    @property
    def test(self) -> Expression: ...
    @property
    def true_branch(self) -> Statement: ...


class JumpStatement(Statement):
    @property
    def expr(self) -> Expression: ...
    @property
    def operator(self) -> NssToken: ...


class LabelStatement(Statement):
    @property
    def expr(self) -> Expression: ...
    @property
    def label(self) -> NssToken: ...


class LiteralExpression(Expression):
    @property
    def literal(self) -> NssToken: ...


class LiteralVectorExpression(Expression):
    @property
    def x(self) -> NssToken: ...
    @property
    def y(self) -> NssToken: ...
    @property
    def z(self) -> NssToken: ...


class LogicalExpression(Expression):
    @property
    def lhs(self) -> Expression: ...
    @property
    def operator(self) -> NssToken: ...
    @property
    def rhs(self) -> Expression: ...


class Nss:
    def __init__(self, filename: Path, ctx: Context,
                 is_command_script: bool = False): ...

    def ast(self) -> Ast: ...
    def complete(self, needle: str) -> Sequence["Symbol"]: ...

    def complete_at(self, needle: str, line: int,
                    character: int) -> Sequence["Symbol"]: ...

    def complete_dot(self, needle: str, line: int,
                     character: int) -> Sequence["Symbol"]: ...

    def dependencies(self) -> Set[str]: ...
    def diagnostics(self) -> List[Diagnostic]: ...
    def errors(self) -> int: ...
    def exports(self) -> List["Symbol"]: ...

    def locate_export(self, is_type: bool,
                      search_dependencies: bool = False) -> Symbol: ...

    def locate_symbol(self, symbol: str, line: int,
                      character: int) -> "Symbol": ...

    def name(self) -> str: ...
    def parse(self) -> None: ...
    def process_includes(self, parent: Nss) -> Any: ...
    def resolve(self) -> None: ...
    def signature_help(self, line: int, character: int) -> SignatureHelp: ...
    def type_name(self, node: AstNode) -> str: ...
    def view_from_range(self, range: SourceRange) -> str: ...
    def warnings(self) -> int: ...

    @staticmethod
    def from_string(script: str, ctx: Context,
                    is_command_script: bool = False) -> Nss: ...


class NssLexer:
    def __init__(self, script: str, ctx: Context) -> None: ...
    def current(self) -> NssToken: ...
    def next(self) -> NssToken: ...


class NssToken:
    @property
    def type(self) -> NssTokenType: ...
    @property
    def loc(self) -> SourceLocation: ...


class NssTokenType:
    __members__: ClassVar[dict] = ...  # read-only
    ACTION: ClassVar[NssTokenType] = ...
    AND: ClassVar[NssTokenType] = ...
    ANDAND: ClassVar[NssTokenType] = ...
    ANDEQ: ClassVar[NssTokenType] = ...
    BREAK: ClassVar[NssTokenType] = ...
    CASE: ClassVar[NssTokenType] = ...
    CASSOWARY: ClassVar[NssTokenType] = ...
    COLON: ClassVar[NssTokenType] = ...
    COMMA: ClassVar[NssTokenType] = ...
    CONST: ClassVar[NssTokenType] = ...
    CONTINUE: ClassVar[NssTokenType] = ...
    DEFAULT: ClassVar[NssTokenType] = ...
    DIV: ClassVar[NssTokenType] = ...
    DIVEQ: ClassVar[NssTokenType] = ...
    DO: ClassVar[NssTokenType] = ...
    DOT: ClassVar[NssTokenType] = ...
    EFFECT: ClassVar[NssTokenType] = ...
    ELSE: ClassVar[NssTokenType] = ...
    END: ClassVar[NssTokenType] = ...
    EQ: ClassVar[NssTokenType] = ...
    EQEQ: ClassVar[NssTokenType] = ...
    EVENT: ClassVar[NssTokenType] = ...
    FLOAT: ClassVar[NssTokenType] = ...
    FLOAT_CONST: ClassVar[NssTokenType] = ...
    FOR: ClassVar[NssTokenType] = ...
    GT: ClassVar[NssTokenType] = ...
    GTEQ: ClassVar[NssTokenType] = ...
    IDENTIFIER: ClassVar[NssTokenType] = ...
    IF: ClassVar[NssTokenType] = ...
    INT: ClassVar[NssTokenType] = ...
    INTEGER_CONST: ClassVar[NssTokenType] = ...
    INVALID: ClassVar[NssTokenType] = ...
    ITEMPROPERTY: ClassVar[NssTokenType] = ...
    JSON: ClassVar[NssTokenType] = ...
    JSON_CONST: ClassVar[NssTokenType] = ...
    LBRACE: ClassVar[NssTokenType] = ...
    LBRACKET: ClassVar[NssTokenType] = ...
    LOCATION: ClassVar[NssTokenType] = ...
    LOCATION_INVALID: ClassVar[NssTokenType] = ...
    LPAREN: ClassVar[NssTokenType] = ...
    LT: ClassVar[NssTokenType] = ...
    LTEQ: ClassVar[NssTokenType] = ...
    MINUS: ClassVar[NssTokenType] = ...
    MINUSEQ: ClassVar[NssTokenType] = ...
    MINUSMINUS: ClassVar[NssTokenType] = ...
    MOD: ClassVar[NssTokenType] = ...
    MODEQ: ClassVar[NssTokenType] = ...
    NOT: ClassVar[NssTokenType] = ...
    NOTEQ: ClassVar[NssTokenType] = ...
    OBJECT: ClassVar[NssTokenType] = ...
    OBJECT_INVALID_CONST: ClassVar[NssTokenType] = ...
    OBJECT_SELF_CONST: ClassVar[NssTokenType] = ...
    OR: ClassVar[NssTokenType] = ...
    OREQ: ClassVar[NssTokenType] = ...
    OROR: ClassVar[NssTokenType] = ...
    PLUS: ClassVar[NssTokenType] = ...
    PLUSEQ: ClassVar[NssTokenType] = ...
    PLUSPLUS: ClassVar[NssTokenType] = ...
    POUND: ClassVar[NssTokenType] = ...
    QUESTION: ClassVar[NssTokenType] = ...
    RBRACE: ClassVar[NssTokenType] = ...
    RBRACKET: ClassVar[NssTokenType] = ...
    RETURN: ClassVar[NssTokenType] = ...
    RPAREN: ClassVar[NssTokenType] = ...
    SEMICOLON: ClassVar[NssTokenType] = ...
    SL: ClassVar[NssTokenType] = ...
    SLEQ: ClassVar[NssTokenType] = ...
    SQLQUERY: ClassVar[NssTokenType] = ...
    SR: ClassVar[NssTokenType] = ...
    SREQ: ClassVar[NssTokenType] = ...
    STRING: ClassVar[NssTokenType] = ...
    STRING_CONST: ClassVar[NssTokenType] = ...
    STRING_RAW_CONST: ClassVar[NssTokenType] = ...
    STRUCT: ClassVar[NssTokenType] = ...
    SWITCH: ClassVar[NssTokenType] = ...
    TALENT: ClassVar[NssTokenType] = ...
    TILDE: ClassVar[NssTokenType] = ...
    TIMES: ClassVar[NssTokenType] = ...
    TIMESEQ: ClassVar[NssTokenType] = ...
    USR: ClassVar[NssTokenType] = ...
    USREQ: ClassVar[NssTokenType] = ...
    VECTOR: ClassVar[NssTokenType] = ...
    VOID: ClassVar[NssTokenType] = ...
    WHILE: ClassVar[NssTokenType] = ...
    XOR: ClassVar[NssTokenType] = ...
    XOREQ: ClassVar[NssTokenType] = ...
    __entries: ClassVar[dict] = ...
    def __init__(self, value: int) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __getstate__(self) -> int: ...
    def __hash__(self) -> int: ...
    def __index__(self) -> int: ...
    def __int__(self) -> int: ...
    def __ne__(self, other: object) -> bool: ...
    def __setstate__(self, state: int) -> None: ...
    @property
    def name(self) -> str: ...
    @property
    def value(self) -> int: ...


class PostfixExpression(Expression):
    @property
    def lhs(self) -> Expression: ...
    @property
    def operator(self) -> NssToken: ...


class Include:
    resref: str
    location: SourceLocation
    script: Nss
    used: int


class Comment:
    def __str__(self) -> str: ...


class Ast:
    def __getitem__(self, index: int) -> AstNode: ...
    def __iter__(self) -> Iterator: ...
    def __len__(self) -> int: ...
    @property
    def defines(self) -> List[Tuple[str, str]]: ...
    @property
    def includes(self) -> List[Include]: ...
    def comments(self) -> List[Comment]: ...
    def find_comment(self, line: int) -> str: ...


class Statement(AstNode):
    pass


class StructDecl(Declaration):
    def __getitem__(self, index: int) -> Declaration: ...
    def __len__(self) -> int: ...
    def __iter__(self) -> Iterator: ...
    def locate_member_decl(self, name: str) -> Optional[Declaration]: ...


class SwitchStatement(Statement):
    @property
    def block(self) -> Statement: ...
    @property
    def target(self) -> Expression: ...


class Type:
    @property
    def struct_id(self) -> NssToken: ...
    @property
    def type_qualifier(self) -> NssToken: ...
    @property
    def type_specifier(self) -> NssToken: ...


class UnaryExpression(Expression):
    @property
    def operator(self) -> NssToken: ...
    @property
    def rhs(self) -> Expression: ...


class VarDecl(Declaration):
    @property
    def init(self) -> Expression: ...


class VariableExpression(Expression):
    @property
    def var(self) -> NssToken: ...


class WhileStatement(Statement):
    @property
    def block(self) -> Statement: ...
    @property
    def test(self) -> Expression: ...
