import { Readline } from "readline/promises";


declare class CiaoPromiseProxy {
    hasValue: boolean;
    // TODO
    // value: | null;
    // handler: | null;
    // next: | null;

    constructor(root_URL): CiaoPromiseProxy;

    // TODO
    // setValue(value: | undefined): void;
    // then(handler: );
    // static resolve(value: ): CiaoPromiseProxy;
}

// TODO
// declare function new_LLCiao(): ;
declare function ciao_worker_fun(): void;
declare function ciao_worker_url(): string;

declare let use_webworker: boolean;

declare class CiaoWorker {
    eng_loaded: boolean;
    eng_booted: boolean;
    listeners: CiaoPromiseProxy[];
    // TODO
    llciao: LLCiao | undefined;
    pending_level: number;
    root_URL: string;
    w: Worker | undefined;

    constructor(root_URL: string): CiaoWorker;
    #async(cmd: string, args: string[]): CiaoPromiseProxy | Promise<QueryResponse>;
    ensure_init(level: number): Promise<void>;
    use_bundle(name: string): CiaoPromiseProxy | Promise<QueryResponse>;
    wait_no_deps(): CiaoPromiseProxy | Promise<QueryResponse>;
    get_stats(): CiaoPromiseProxy | Promise<QueryResponse>;
    get_ciao_root(): CiaoPromiseProxy | Promise<QueryResponse>;
    query_one_begin(goal: string): CiaoPromiseProxy | Promise<QueryResponse>;
    query_one_next(): CiaoPromiseProxy | Promise<QueryResponse>;
    #query_complete(q_out: QueryResponse): CiaoPromiseProxy | Promise<QueryResponse>;
    query_resume_dbgtrace(dbgcmd: string): CiaoPromiseProxy | Promise<QueryResponse>;
    query_end(): Promise<any>;
    async readFile(path: string): CiaoPromiseProxy | Promise<QueryResponse>;
    async writeFile(path: string, contents: string): CiaoPromiseProxy | Promise<QueryResponse>;
    async read_stdout(): CiaoPromiseProxy | Promise<QueryResponse>;
    async read_stderr(): CiaoPromiseProxy | Promise<QueryResponse>;
    terminate(): void;
}

// TODO
// declare let jsref_heap: [];
// declare let jsref_freeidx: ;

declare function jsref_free(idx: number): void;

declare type jsmcd = {
    name: string,
    code: string,
    args: string[]
};
declare let jscmd_f: jsmcd[];

declare async function jscmd_run(w: Worker, jscmd: jsmcd): void;

declare const toplevelCfg_defaults: {
    statistics: boolean;
    query_timeout: number;
    special_query: {
        use_module: {
            read_code: boolean, mark_errs: boolean
        },
        run_tests_in_module: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        doc_cmd: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        set_menu_flag: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        module: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        auto_analyze: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        auto_optimize: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        auto_check_assert: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        filter_analyze: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        },
        filter_analyze_exercise_mode: {
            read_code: boolean,
            mark_errs: boolean,
            depends: string[],
            on_init: string[]
        }
    };
    init_bundles: string[],
    init_queries: string[]
}

declare class ToplevelProc {
    // TODO
    // comint: | null;
    muted: boolean;
    q_opts: {};
    root_URL: string;
    state: QueryState | null;
    timer: NodeJS.Timeout | undefined;
    w: Worker | null;

    constructor(root_URL: string): ToplevelProc;
    is_started(): boolean;
    async start(): Promise<void>;
    async restart(): Promise<void>;
    shutdown(): void;
    // TODO
    // async ensure_started(comint: ): Promise<void>;
    set_muted(v: boolean): boolean;
    async load_ciao_defaults(): Promise<boolean>;
    async push_on_init(qs: string[]): Promise<void>;
    async push_depends(bs: string[]): Promise<void>;
    async muted_query_dumpout(q: string): Promise<void>;
    async dumpout(): Promise<void>;
    set_query_timeout(): void;
    cancel_query_timeout(): void;
    // TODO
    // async trans_query(query: string): Promise<{
    //     q: string;
    //     treat_outerr: ((out: , err: ) => Promise<void>) | null;
    // }>;
    // update_state(state: ): void;
    check_not_running(): boolean;
    // TODO
    // check_not_locked(comint: ): boolean;
    is_waiting_for_line(): boolean;
    // TODO
    // async run_query(comint: , query: string, opts: ): Promise<void>;
    // async send_line(comint: , action: string): Promise<void>;
    async treat_sol(q_out: QueryResponse, treat_outerr: booean | null): Promise<void>;
    async abort(): Promise<void>;

}

declare const ENVIRONMENT_IS_NODE: boolean;

declare class RLPGCell {
    // TODO
    // cproc: ;
    // constructor(cproc: ): RLPGCell;
    async setup(rl: Readline.Interface): Promise<void>;
    async on_cproc_start(): Promise<void>;
    show_version(str: string): void;
    async upload_code_to_worker(): Promise<void>;
    // TODO
    // mark_errs(out: , err: ): void;
    mark_srcdbg_info(info): void;
}

declare class RLComint {
    prompt: '?- ';
    promptval: ' ? ';
    with_prompt: boolean;
    pg: RLPGCell;
    rl: Readline.Interface;
    next_prompt: string;

    // TODO
    // constructor(rl: Readline.Interface, pg: RLPGCell, opts: ): RLComint;
    update_inner_layout(): void;
    display(text: string): void;
    print_out(str: string): void;
    print_sol(str: string): void;
    print_msg(str: string): void;
    print_prompt(): void;
    print_promptval(): void;
    display_status(str: string): void;
    display_status_new_prompt(str): void;
    set_log(text: string): void;
    async #treat_enter_(text: string): Promise<void>;
    async loop(): Promise<void>;
}


declare let toplevelCfg: {
    statistics: boolean;
}
declare let use_webworker: boolean;
declare let is_terminal: boolean;
declare let rl: Readline.Interface;

export { CiaoWorker }