import { HTTPConfig } from "../config/HTTPConfig";
import { MQTTConfig } from "../config/MQTTConfig";
import { IHttpRequester } from "../core/http/IHttpRequester";
import { IMQTTClient } from "../core/mqtt/IMQTTClient";
import { MQTTLogic } from "../core/mqtt/MQTTLogic";
import { ControllerMQTTImpl } from "../core/mqtt/impl/ControllerMQTTImpl";
import { ISDKLogger } from "../util/ISDKLogger";
import { SDKLog } from "../util/SDKLog";
import { ControllerDeviceType } from "../vo/device/ControllerDeviceType";
import { ControllerDeviceVO } from "../vo/device/ControllerDeviceVO";
import { ControllerManager } from "./ControllerManager";
import { IControllerCallback } from "./IControllerCallback";

export class Builder {
    private readonly controllerManager: ControllerManager;
    private readonly device: ControllerDeviceVO;
    private guid: string;

    constructor() {
        this.controllerManager = new ControllerManager();
        this.device = new ControllerDeviceVO();
        this.guid = "";
    }

    initControllerDeviceId(guid: string): Builder {
        this.guid = guid;
        this.device.guid = guid;
        this.controllerManager.setGuid(guid);
        return this;
    }

    initControllerType(type: ControllerDeviceType): Builder {
        this.device.controllerDeviceType = type;
        return this;
    }

    initNetwork(ip: string, gateway: string, mask: string): Builder {
        this.device.ip = ip;
        this.device.gateway = gateway;
        this.device.mask = mask;
        return this;
    }

    /**
    * 设置显示终端事件回调，用于接收并响应与UI相关的事件
    * @param callback 显示终端事件回调
    * @return 构造器实体
    */
    setCallback(callbak: IControllerCallback): Builder {
        this.controllerManager.setCallback(callbak);
        return this;
    }

    /**
    * SDK未提供http请求实现，app需要封装自身的实现，并可以选择对url做自己的配置，不提供则使用sdk内部默认的配置
    * @param requestImpl http请求实现，比如在实现类中封装fetch api
    * @param config http服务器配置项实现，用于配置符合条件的各项参数
    * @param isTestServer 是否使用测试服，默认为false即使用正式服
    * @return 构造器实体
    */
    setHttpRequestImpl(requestImpl: IHttpRequester, config: HTTPConfig, isTestServer: boolean): Builder {
        config.setTestEnable(isTestServer);
        this.controllerManager.setHttpRequester(requestImpl).setHttpConfig(config);
        return this;
    }

    /**
    * SDK目前未提供mqtt实现，需app进行设置，否则无法完成mqtt请求
    * 请务必在initControllerDeviceId函数之后调用
    * @param clientImpl mqtt实现的封装，比如在实现类中封装Paho mqtt库
    * @param config mqtt服务器配置项实现，用于配置符合条件的各项参数
    * @param isTestServer 是否使用测试服，默认为false即使用正式服
    * @return 构造器实体
    */
    setMQTTClientImpl(clientImpl: IMQTTClient, config: MQTTConfig, isTestServer: boolean): Builder {
        if ("" === this.guid) {
            throw new Error("initControllerDeviceId must be called first");
        }
        let logic: MQTTLogic = new ControllerMQTTImpl(this.guid, this.controllerManager);
        config.setTestEnable(isTestServer);
        logic.setMQTTClientImpl(clientImpl, config);
        this.controllerManager.setMQTTLib(logic);
        return this;
    }

    setSDKLogger(logger: ISDKLogger): Builder {
        SDKLog.setImpl(logger);
        return this;
    }

    build(): ControllerManager {
        this.controllerManager.createControllerDevice(this.device);
        return this.controllerManager;
    }
}