/**
 *
 * This file is auto-generated. Do not edit manually: changes may be erased.
 * Generated by Aqua compiler: https://github.com/fluencelabs/aqua/.
 * If you find any bugs, please write an issue on GitHub: https://github.com/fluencelabs/aqua/issues
 * Aqua version: 0.3.0-224
 *
 */
import { FluencePeer } from "@fluencelabs/fluence";
import {
  ResultCodes,
  RequestFlow,
  RequestFlowBuilder,
  CallParams,
} from "@fluencelabs/fluence/dist/internal/compilerSupport/v1";

// Services

export interface HelloPeerDef {
  hello: (from: string, callParams: CallParams<"from">) => string;
}

export function registerHelloPeer(service: HelloPeerDef): void;
export function registerHelloPeer(
  serviceId: string,
  service: HelloPeerDef
): void;
export function registerHelloPeer(
  peer: FluencePeer,
  service: HelloPeerDef
): void;
export function registerHelloPeer(
  peer: FluencePeer,
  serviceId: string,
  service: HelloPeerDef
): void;
export function registerHelloPeer(...args: any) {
  let peer: FluencePeer;
  let serviceId: any;
  let service: any;
  if (FluencePeer.isInstance(args[0])) {
    peer = args[0];
  } else {
    peer = FluencePeer.default;
  }

  if (typeof args[0] === "string") {
    serviceId = args[0];
  } else if (typeof args[1] === "string") {
    serviceId = args[1];
  } else {
    serviceId = "HelloPeer";
  }

  if (!FluencePeer.isInstance(args[0]) && typeof args[0] === "object") {
    service = args[0];
  } else if (typeof args[1] === "object") {
    service = args[1];
  } else {
    service = args[2];
  }

  peer.internals.callServiceHandler.use((req, resp, next) => {
    if (req.serviceId !== serviceId) {
      next();
      return;
    }

    if (req.fnName === "hello") {
      const callParams = {
        ...req.particleContext,
        tetraplets: {
          from: req.tetraplets[0],
        },
      };
      resp.retCode = ResultCodes.success;
      resp.result = service.hello(req.args[0], callParams);
    }

    next();
  });
}

// Functions

export function sayHello(
  targetPeerId: string,
  targetRelayPeerId: string,
  config?: { ttl?: number }
): Promise<string>;
export function sayHello(
  peer: FluencePeer,
  targetPeerId: string,
  targetRelayPeerId: string,
  config?: { ttl?: number }
): Promise<string>;
export function sayHello(...args: any) {
  let peer: FluencePeer;
  let targetPeerId: any;
  let targetRelayPeerId: any;
  let config: any;
  if (FluencePeer.isInstance(args[0])) {
    peer = args[0];
    targetPeerId = args[1];
    targetRelayPeerId = args[2];
    config = args[3];
  } else {
    peer = FluencePeer.default;
    targetPeerId = args[0];
    targetRelayPeerId = args[1];
    config = args[2];
  }

  let request: RequestFlow;
  const promise = new Promise<string>((resolve, reject) => {
    const r = new RequestFlowBuilder()
      .disableInjections()
      .withRawScript(
        `
     (xor
 (seq
  (seq
   (seq
    (seq
     (seq
      (seq
       (seq
        (seq
         (call %init_peer_id% ("getDataSrv" "-relay-") [] -relay-)
         (call %init_peer_id% ("getDataSrv" "targetPeerId") [] targetPeerId)
        )
        (call %init_peer_id% ("getDataSrv" "targetRelayPeerId") [] targetRelayPeerId)
       )
       (call -relay- ("op" "noop") [])
      )
      (call targetRelayPeerId ("op" "noop") [])
     )
     (xor
      (call targetPeerId ("HelloPeer" "hello") [%init_peer_id%] res)
      (seq
       (seq
        (seq
         (call targetRelayPeerId ("op" "noop") [])
         (call -relay- ("op" "noop") [])
        )
        (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 1])
       )
       (call -relay- ("op" "noop") [])
      )
     )
    )
    (call targetRelayPeerId ("op" "noop") [])
   )
   (call -relay- ("op" "noop") [])
  )
  (xor
   (call %init_peer_id% ("callbackSrv" "response") [res])
   (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 2])
  )
 )
 (call %init_peer_id% ("errorHandlingSrv" "error") [%last_error% 3])
)

                 `
      )
      .configHandler((h) => {
        h.on("getDataSrv", "-relay-", () => {
          return peer.connectionInfo.connectedRelay;
        });
        h.on("getDataSrv", "targetPeerId", () => {
          return targetPeerId;
        });
        h.on("getDataSrv", "targetRelayPeerId", () => {
          return targetRelayPeerId;
        });
        h.onEvent("callbackSrv", "response", (args) => {
          const [res] = args;
          resolve(res);
        });

        h.onEvent("errorHandlingSrv", "error", (args) => {
          const [err] = args;
          reject(err);
        });
      })
      .handleScriptError(reject)
      .handleTimeout(() => {
        reject("Request timed out for sayHello");
      });
    if (config && config.ttl) {
      r.withTTL(config.ttl);
    }
    request = r.build();
  });
  peer.internals.initiateFlow(request!);
  return promise;
}
