import { PayloadAction } from '@reduxjs/toolkit';
import { DebugProtocol } from 'vscode-debugprotocol';
import { DebuggerFileExtension, FileFolderType, ICodeDescriptor, ISource } from '@ws-ui/shared';

export interface IExpression {
    label: string;
    result?: string;
    nakedResult?: string;
    variablesReference?: number;
    presentationHint?: IVariablePresentationHint;
}
export interface IBreakpoint extends DebugProtocol.SourceBreakpoint {
    lineInEditor?: number;
    verified?: boolean;
    disabled?: boolean;
}
export type IDebuggerFileType = FileFolderType.METHOD | FileFolderType.CLASS;
interface IBreakpointsData {
    locations: IBreakpoint[];
    offset?: number;
}
export type IDebuggerData = {
    filePath: string;
    fileType: IDebuggerFileType;
    methodName: string;
    className?: string;
    ext: DebuggerFileExtension;
    source: ISource;
    breakpoints: {
        draft: IBreakpointsData;
        saved: IBreakpointsData;
    };
};
export type BreakpointType = keyof IDebuggerData['breakpoints'];
export interface IVariablePresentationHint extends DebugProtocol.VariablePresentationHint {
    iconID: number;
}
export interface IVariable extends DebugProtocol.Variable {
    nakedValue: string;
    presentationHint?: IVariablePresentationHint;
}
export interface IStackFrame extends DebugProtocol.StackFrame {
    source: DebugProtocol.Source & {
        codeDescriptorInfo?: ICodeDescriptor;
        content?: string;
    };
    offset: number;
    lineIndex: number;
}
export interface ICommonVariable {
    variablesReference: number;
    items: IVariable[];
}
export interface ICallChainVariable extends ICommonVariable {
    frameId: number;
}
export interface ILocalVariable extends ICommonVariable {
    frameId: number;
}
export interface ICurrentLineVariable extends ICommonVariable {
    frameId: number;
}
export interface IExpressionVariable extends ICommonVariable {
}
export type ISessionVariable = ICallChainVariable | ILocalVariable | ICurrentLineVariable | IExpressionVariable;
export interface IException {
    errMess: string;
    location: string;
    locationLine: number;
    formula: string;
    formulaError_begin: number;
    formulaError_end: number;
    formulaError_indent?: number;
    errorIdentifier: string;
}
export interface IFdException extends IException {
    locationLineIndex: number;
}
export interface IDebuggerSession {
    tabPath: string;
    threadId: number;
    channelId: number;
    stackFrames: IStackFrame[];
    currentStackFrame: IStackFrame;
    exceptions: IException[];
    expressions: IExpression[];
    highlightedLines: {
        start: number;
        end?: number;
    } | null;
    activeLine: number | null;
    variables: {
        callchain: ICallChainVariable[];
        expressions: IExpressionVariable[];
        local: ILocalVariable[];
        currentLine: ICurrentLineVariable[];
    };
    stopped?: boolean;
}
export type DebuggerVariablesKey<K extends string = ''> = keyof Omit<IDebuggerSession['variables'], K>;
export type CommonDebuggerVariablesKey = DebuggerVariablesKey<'expressions' | 'callchain'>;
export interface IBreakpointDecoration {
    line: number;
    lineInEditor?: number;
    offset?: number;
    type?: BreakpointType;
}
export type IAddBreakpointAction = PayloadAction<{
    filePath: string;
    fileType: IDebuggerFileType;
    methodName: string;
    className?: string;
    ext: DebuggerFileExtension;
    source: ISource;
    breakpoint: IBreakpointDecoration;
}>;
export type IRemoveBreakpointAction = PayloadAction<{
    filePath: string;
    methodName: string;
    line: number;
    offset?: number;
    type?: BreakpointType;
}>;
export type ISetBreakpointsAction = PayloadAction<{
    filePath: string;
    fileType: IDebuggerFileType;
    methodName: string;
    className?: string;
    ext: DebuggerFileExtension;
    source: ISource;
    breakpoints: IBreakpoint[];
    offset?: number;
    type?: BreakpointType;
    clearDraft?: boolean;
    merge?: boolean;
}>;
export type IUpdateBreakpointsAction = PayloadAction<{
    filePath: string;
    fileType: IDebuggerFileType;
    methodName: string;
    className?: string;
    breakpoints: IBreakpoint[];
    type?: BreakpointType;
    merge?: boolean;
}>;
export type IToggleBreakpointAction = PayloadAction<{
    filePath: string;
    methodName: string;
    line: number;
    offset?: number;
    disabled: boolean;
}>;
export type IToggleBreakpointsInFileAction = PayloadAction<{
    filePath: string;
    methodName: string;
    disabled: boolean;
}>;
export type IClearBreakpointsAction = PayloadAction<{
    filePath: string;
    type?: BreakpointType | 'any';
}>;
export type IClearBreakpointsExceptAction = PayloadAction<{
    exceptedFilePath: string;
    type?: BreakpointType | 'any';
}>;
export type ISetActiveLineAction = PayloadAction<{
    threadId: number;
    line: number;
    highlight?: boolean;
}>;
export type IAddExpressionAction = PayloadAction<{
    threadId: number;
    label: string;
    save?: boolean;
}>;
export type IRemoveExpressionAction = PayloadAction<{
    threadId: number;
    index: number;
    save?: boolean;
}>;
export type IRemoveAllExpressionsAction = PayloadAction<{
    threadId: number;
    save?: boolean;
}>;
export type IRenameExpressionAction = PayloadAction<{
    threadId: number;
    index: number;
    replacement: string;
    save?: boolean;
}>;
export type ISetExpressionAction = PayloadAction<{
    threadId: number;
    expression: IExpression & {
        index: number;
    };
}>;
export type IUpdateExpressionAtAction = PayloadAction<{
    threadId: number;
    index: number;
    value: IExpression['result'];
}>;
export type ISaveExpressionsAction = PayloadAction<{
    expressions: IExpression[];
}>;
export type IAddSessionAction = PayloadAction<{
    threadId: number;
    channelId: number;
    stackFrames: IStackFrame[];
    exceptions?: IException[];
}>;
export type IUpdateSessionAction = PayloadAction<{
    threadId: number;
    changes: Partial<IDebuggerSession>;
}>;
export type IRemoveSessionAction = PayloadAction<{
    threadId: number;
}>;
export type ISetCommonVariablesAction = PayloadAction<{
    key: CommonDebuggerVariablesKey;
    threadId: number;
    frameId: number;
    variablesReference: number;
    variables: IVariable[];
}>;
export type ISetCallChainVariablesAction = PayloadAction<{
    threadId: number;
    frameId: number;
    variablesReference: number;
    variables: IVariable[];
}>;
export type ISetExpressionVariablesAction = PayloadAction<{
    threadId: number;
    variablesReference: number;
    variables: IVariable[];
}>;
export type ISetSourceContentAction = PayloadAction<{
    threadId: number;
    content: string;
}>;
export declare enum ExpressionIndex {
    First = 0,
    Last = -1
}
export declare enum EDebuggerState {
    ATTACHED = "attached",
    DETACHED = "detached",
    ERROR = "error"
}
export declare enum EDebuggerErrorType {
    SOCKET_ERROR = "socket-error",
    SOCKET_CLOSURE = "socket-closure"
}
export declare enum EDebuggerErrorReason {
    NOT_STARTED = "remote debugger not started",
    ALREADY_IN_USE = "already in use",
    TIMEOUT = "timeout"
}
type IDebuggerError = Partial<{
    code: number | null;
    reason: string;
    type: EDebuggerErrorType;
}>;
export interface IDebuggerMeta {
    state: EDebuggerState;
    error?: IDebuggerError & {
        time: number;
    };
}
export type ISetDebuggerMetaAction = PayloadAction<{
    state: EDebuggerState;
    error?: IDebuggerError;
}>;
export interface IEnhancedBreakpoint extends IBreakpoint {
    offset?: number;
    fileType: IDebuggerFileType;
    filePath: string;
    methodName: string;
    className?: string;
    ext: DebuggerFileExtension;
}
export interface IBreakpointsByFile {
    file: {
        path: string;
        type: IDebuggerFileType;
        methodName: string;
        className?: string;
        ext: DebuggerFileExtension;
    };
    breakpoints: IEnhancedBreakpoint[];
}
export {};
