import type http from "@ohos:net.http";
import { Chain } from "@normalized:N&&&@yic/http/src/main/ets/core/Chain&1.0.1";
import type { RequestBody } from '../requestbody/RequestBody';
import type Task from './Task';
import type { TaskDispatch } from './TaskDispatch';
/**
 * @ProjectName : HarmonyUtilSdk
 * @FileName : DefaultTaskDispatch
 * @Author : yic
 * @Time : 2024/6/20 16:04
 * @Description : 文件描述
 */
export class DefaultTaskDispatch implements TaskDispatch {
    private MAX = 5;
    private workingList: Task[] = [];
    private waitingList: Task[] = [];
    cancel(tag: string) {
        if (!tag || tag.length == 0) {
            return;
        }
        this.workingList.forEach((it) => {
            if (it.requestBody.getTag() === tag) {
                it.requestBody.cancel();
            }
        });
        //从等待列表中移除
        this.waitingList = this.waitingList.filter((it) => { return it.requestBody.getTag() !== tag; });
    }
    dispatch(requestBody: RequestBody): Promise<http.HttpResponse> {
        return new Promise<http.HttpResponse>((resolve, reject) => {
            const task: Task = {
                requestBody: requestBody,
                resolve: resolve,
                reject: reject
            };
            //该参数一般测试模式使用,表示直接执行了
            if (task.requestBody.isExpressed()) {
                getContext();
                this.workingList.push(task);
                task.requestBody.execute(new Chain(task.requestBody))
                    .then((response) => {
                    this.done(task.requestBody);
                    task.resolve(response);
                }).catch((err) => {
                    this.done(task.requestBody);
                    task.reject(err);
                });
            }
            else {
                const workingIndex = this.workingList.findIndex((it) => {
                    return it.requestBody.getUrlWithParam() === task.requestBody.getUrlWithParam();
                });
                const waitingIndex = this.waitingList.findIndex((it) => {
                    return it.requestBody.getUrlWithParam() === task.requestBody.getUrlWithParam();
                });
                //根据url+params生成判断是否已经在处理中,或者已经在等待队列中，是的话就不处理了
                if (workingIndex >= 0 || waitingIndex >= 0) {
                    return;
                }
                if (workingIndex === -1) {
                    if (this.workingList.length < this.MAX) {
                        this.workingList.push(task);
                        task.requestBody.execute(new Chain(task.requestBody))
                            .then((response) => {
                            this.done(task.requestBody);
                            task.resolve(response);
                        }).catch((err) => {
                            this.done(task.requestBody);
                            task.reject(err);
                        });
                    }
                    else {
                        //找到等待队列中相同的接口,如果没有就直接添加到等待队列中,如果存在就移除然后添加到等待队列中
                        const waitingIndex = this.waitingList.findIndex((it) => {
                            return it.requestBody.getUrlWithParam() === task.requestBody.getUrlWithParam();
                        });
                        if (waitingIndex === -1) {
                            this.waitingList.push(task);
                        }
                        else {
                            this.waitingList.slice(waitingIndex, 1);
                            this.waitingList.push(task);
                        }
                    }
                }
            }
        });
    }
    done(requestBody: RequestBody) {
        this.workingList = this.workingList.filter((it) => {
            return it.requestBody !== requestBody;
        });
        if (this.waitingList.length > 0 && this.workingList.length < this.MAX) {
            const task = this.waitingList.shift();
            this.workingList.push(task);
            task.requestBody.execute(new Chain(task.requestBody))
                .then((response) => {
                this.done(task.requestBody);
                task.resolve(response);
            }).catch((err) => {
                task.reject(err);
            });
        }
    }
}
