import { DASFConnection, DigitalEarthUrlBuilder, DASFModuleResponse, DASFProgressReport, DASFModuleRequest, DASFModuleRequestReceipt } from "dasf-messaging-typescript";

/**
 * Works with
 * https://git.geomar.de/digital-earth/dasf/dasf-messaging-python/-/blob/master/ExampleMessageConsumer.py
 */
const DASF_TOPIC = "mytesttopic";

export default class ExampleModuleMessaging {
    private connection: DASFConnection;

    public constructor() {
        this.connection = new DASFConnection(new DigitalEarthUrlBuilder(DASF_TOPIC));
    }

    public isConnected(): boolean {
        return this.connection.isBackendConnected();
    }

    public sendHelloWorldRequest(greetMessage: string, repeatMessage: string, repeat: number): Promise<Record<string, unknown>> {
      return new Promise((resolve: (value: Record<string, unknown>) => void, reject: (reason: string) => void) => {
        this.connection.sendRequest(this.createHelloWorldRequest(greetMessage, repeatMessage, repeat), (response: DASFModuleResponse) => {
            if(response.properties.status == 'success') {
              resolve(JSON.parse(atob(response.payload)))
            } else {
              reject(atob(response.payload))
            }
        }, 
        null, 
        (receipt: DASFModuleRequestReceipt) => {
          reject(receipt.errorMsg)  
        });
      })
    }

    private createHelloWorldRequest(greetMessage: string, repeatMessage: string, repeat: number): DASFModuleRequest {
        let request = DASFModuleRequest.createRequestMessage();

        let moduleCall: object = {
          func_name: "hello_world",
          message: greetMessage,
          repeat: repeat,
          greet_message: repeatMessage,
        }

        request.payload = btoa( JSON.stringify( moduleCall ) )

        return request;
    }

    public sendProgressReportRequest(onProgress: (report: DASFProgressReport) => void): Promise<void> {
      return new Promise((resolve: () => void, reject: (reason: string) => void) => {
        this.connection.sendRequest(this.createProgressDemoRequest(), (response: DASFModuleResponse) => {
            if(response.properties.status == 'success') {
              resolve()
            } else {
              reject(atob(response.payload))
            }
        }, 
        onProgress, 
        (receipt: DASFModuleRequestReceipt) => {
          reject(receipt.errorMsg)  
        });
      })
    }

    private createProgressDemoRequest(): DASFModuleRequest {
      let request = DASFModuleRequest.createRequestMessage();

      let moduleCall: object = {
        func_name: "report_progress_demo",
        reporter: { report_type: 'tree', report_id: 'root', status: 'running', step_message: 'some root progress message', steps: 0, children: [] },
      }

      request.payload = btoa( JSON.stringify( moduleCall ) )

      return request;
  }
}
