package ch.polgrabia.demos.client;

import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.ext.web.Router;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WebApiParticle extends AbstractVerticle {
  private static final Logger logger = LoggerFactory.getLogger(WebApiParticle.class);
  private final int clientPort;
  private HttpServer server;

  public WebApiParticle(int clientPort) {
    this.clientPort = clientPort;
  }

  @Override
  public void start() throws Exception {
    HttpServerOptions httpServerOptions = new HttpServerOptions();
    var router = Router.router(getVertx());
    this.server = getVertx().createHttpServer(httpServerOptions);
    router.get("/message").respond(routingContext -> handleCommandRequests(routingContext.request()));
    this.server.requestHandler(router);
    this.server.listen(clientPort, "localhost", this::handleListenCommand);
  }

  @Override
  public void stop() throws Exception {
    server.close();
  }

  private Future<Void> handleCommandRequests(HttpServerRequest httpServerRequest) {
    logger.info("Received command request on {}", clientPort);
    HttpServerResponse response = httpServerRequest.response();
    String qParam = httpServerRequest.getParam("q");
    if (qParam == null || qParam.isBlank()) {
      response.setStatusCode(HttpResponseStatus.BAD_REQUEST.code());
      return response.end("%s\n".formatted(HttpResponseStatus.BAD_REQUEST.reasonPhrase()));
    }
    logger.info("Sending binary message: {}", qParam);
    getVertx().eventBus().publish(Constants.CLIENT_WEBSOCKET_SENDER_EVENTBUS_KEY, Buffer.buffer(qParam));
    response.setStatusCode(HttpResponseStatus.ACCEPTED.code());
    return response.end("%s\n".formatted(HttpResponseStatus.ACCEPTED.reasonPhrase()));
  }

  private void handleListenCommand(AsyncResult<HttpServer> httpServerAsyncResult) {
    if (httpServerAsyncResult.failed()) {
      logger.warn("Couldn't initialized http command server");
      getVertx().close();
      System.exit(1);
    }

    logger.info("Successfully started websocket client command server");
  }
}
