// SPDX-License-Identifier: LGPL-2.1-or-later
// Copyright (c) 2012-2014 Monty Program Ab
// Copyright (c) 2015-2021 MariaDB Corporation Ab

package org.mariadb.jdbc.integration.tools;

import java.io.*;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import org.mariadb.jdbc.util.log.Logger;
import org.mariadb.jdbc.util.log.Loggers;

public class TcpProxySocket implements Runnable {
  private static final Logger logger = Loggers.getLogger(TcpProxySocket.class);

  private final String host;
  private final int remoteport;
  private final int localport;
  private boolean stop = false;
  private Socket client = null;
  private Socket server = null;
  private ServerSocket ss;
  private int delay;

  /**
   * Creation of proxy.
   *
   * @param host database host
   * @param remoteport database port
   * @throws IOException exception
   */
  public TcpProxySocket(String host, int remoteport) throws IOException {
    this.host = host;
    this.remoteport = remoteport;
    ss = new ServerSocket(0);
    this.localport = ss.getLocalPort();
  }

  public int getLocalPort() {
    return ss.getLocalPort();
  }

  public boolean isClosed() {
    return ss.isClosed();
  }

  public void setDelay(int delay) {
    this.delay = delay;
  }

  /** Kill proxy. */
  public void kill() {
    stop = true;
    try {
      if (server != null) {
        server.close();
      }
    } catch (IOException e) {
      // eat Exception
    }
    try {
      if (client != null) {
        client.close();
      }
    } catch (IOException e) {
      // eat Exception
    }
    try {
      ss.close();
    } catch (IOException e) {
      // eat Exception
    }
  }

  public void sendRst() {

    try {
      if (client != null) {
        // send an RST, not FIN
        client.setSoLinger(true, 0);
        client.close();
      }
    } catch (IOException e) {
      // eat Exception
    }
    try {
      if (server != null) {
        server.close();
      }
    } catch (IOException e) {
      // eat Exception
    }

    try {
      ss.close();
    } catch (IOException e) {
      // eat Exception
    }
  }

  @Override
  public void run() {

    logger.trace("host proxy port " + this.localport + " for " + host + " started");
    stop = false;
    try {
      try {
        if (ss.isClosed()) {
          ss = new ServerSocket(localport);
        }
      } catch (BindException b) {
        // in case for testing crash and reopen too quickly
        try {
          Thread.sleep(100);
        } catch (InterruptedException i) {
          // eat Exception
        }
        if (ss.isClosed()) {
          ss = new ServerSocket(localport);
        }
      }
      final byte[] request = new byte[1024];
      byte[] reply = new byte[4096];
      while (!stop) {
        try {
          client = ss.accept();
          final InputStream fromClient = client.getInputStream();
          final OutputStream toClient = client.getOutputStream();
          try {
            server = new Socket(host, remoteport);
          } catch (IOException e) {
            PrintWriter out = new PrintWriter(new OutputStreamWriter(toClient));
            out.println("Proxy server cannot connect to " + host + ":" + remoteport + ":\n" + e);
            out.flush();
            client.close();
            continue;
          }
          final InputStream fromServer = server.getInputStream();
          final OutputStream toServer = server.getOutputStream();
          new Thread(
                  () -> {
                    int bytesRead;
                    try {
                      while ((bytesRead = fromClient.read(request)) != -1) {
                        if (delay > 0) {
                          try {
                            Thread.sleep(delay);
                          } catch (InterruptedException e) {
                            e.printStackTrace();
                          }
                        }
                        toServer.write(request, 0, bytesRead);
                        toServer.flush();
                      }
                    } catch (IOException e) {
                      // eat exception
                    }
                    try {
                      toServer.close();
                    } catch (IOException e) {
                      // eat exception
                    }
                  })
              .start();
          int bytesRead;
          try {
            while ((bytesRead = fromServer.read(reply)) != -1) {
              try {
                Thread.sleep(1);
              } catch (InterruptedException e) {
                e.printStackTrace();
              }
              toClient.write(reply, 0, bytesRead);
              toClient.flush();
            }
          } catch (IOException e) {
            // eat exception
          }
          toClient.close();
        } catch (IOException e) {
          // System.err.println("ERROR socket : "+e);
        } finally {
          try {
            if (server != null) {
              server.close();
            }
            if (client != null) {
              client.close();
            }
          } catch (IOException e) {
            // eat exception
          }
        }
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  public int getLocalport() {
    return localport;
  }
}
