// 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.message.client;

import static org.mariadb.jdbc.util.constants.Capabilities.*;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.StringTokenizer;
import org.mariadb.jdbc.Configuration;
import org.mariadb.jdbc.client.Context;
import org.mariadb.jdbc.client.socket.Writer;
import org.mariadb.jdbc.client.socket.impl.PacketWriter;
import org.mariadb.jdbc.message.ClientMessage;
import org.mariadb.jdbc.plugin.Credential;
import org.mariadb.jdbc.plugin.authentication.standard.NativePasswordPlugin;
import org.mariadb.jdbc.util.VersionFactory;

/**
 * Server handshake response builder. see
 * https://mariadb.com/kb/en/connection/#client-handshake-response
 */
public final class HandshakeResponse implements ClientMessage {

  private static final String _CLIENT_NAME = "_client_name";
  private static final String _CLIENT_VERSION = "_client_version";
  private static final String _SERVER_HOST = "_server_host";
  private static final String _OS = "_os";
  private static final String _THREAD = "_thread";
  private static final String _JAVA_VENDOR = "_java_vendor";
  private static final String _JAVA_VERSION = "_java_version";

  private final String username;
  private final CharSequence password;
  private final String database;
  private final String connectionAttributes;
  private final String host;
  private final long clientCapabilities;
  private final byte exchangeCharset;
  private final byte[] seed;
  private String authenticationPluginType;

  /**
   * Object with parsed results
   *
   * @param credential credential
   * @param authenticationPluginType authentication plugin to use
   * @param seed server seed
   * @param conf configuration
   * @param host current host
   * @param clientCapabilities client capabilities
   * @param exchangeCharset connection charset
   */
  public HandshakeResponse(
      Credential credential,
      String authenticationPluginType,
      byte[] seed,
      Configuration conf,
      String host,
      long clientCapabilities,
      byte exchangeCharset) {
    this.authenticationPluginType = authenticationPluginType;
    this.seed = seed;
    this.username = credential.getUser();
    this.password = credential.getPassword();
    this.database = conf.database();
    this.connectionAttributes = conf.connectionAttributes();
    this.host = host;
    this.clientCapabilities = clientCapabilities;
    this.exchangeCharset = exchangeCharset;
  }

  private static void writeStringLengthAscii(Writer encoder, String value) throws IOException {
    byte[] valBytes = value.getBytes(StandardCharsets.US_ASCII);
    encoder.writeLength(valBytes.length);
    encoder.writeBytes(valBytes);
  }

  private static void writeStringLength(Writer encoder, String value) throws IOException {
    byte[] valBytes = value.getBytes(StandardCharsets.UTF_8);
    encoder.writeLength(valBytes.length);
    encoder.writeBytes(valBytes);
  }

  private static void writeConnectAttributes(
      Writer writer, String connectionAttributes, String host) throws IOException {

    PacketWriter tmpWriter = new PacketWriter(null, 0, 0, null, null);
    tmpWriter.pos(0);
    writeStringLengthAscii(tmpWriter, _CLIENT_NAME);
    writeStringLength(tmpWriter, "MariaDB Connector/J");

    writeStringLengthAscii(tmpWriter, _CLIENT_VERSION);
    writeStringLength(tmpWriter, VersionFactory.getInstance().getVersion());

    writeStringLengthAscii(tmpWriter, _SERVER_HOST);
    writeStringLength(tmpWriter, (host != null) ? host : "");

    writeStringLengthAscii(tmpWriter, _OS);
    writeStringLength(tmpWriter, System.getProperty("os.name"));

    writeStringLengthAscii(tmpWriter, _THREAD);
    writeStringLength(tmpWriter, Long.toString(Thread.currentThread().getId()));

    writeStringLengthAscii(tmpWriter, _JAVA_VENDOR);
    writeStringLength(tmpWriter, System.getProperty("java.vendor"));

    writeStringLengthAscii(tmpWriter, _JAVA_VERSION);
    writeStringLength(tmpWriter, System.getProperty("java.version"));

    if (connectionAttributes != null) {
      StringTokenizer tokenizer = new StringTokenizer(connectionAttributes, ",");
      while (tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken();
        int separator = token.indexOf(":");
        if (separator != -1) {
          writeStringLength(tmpWriter, token.substring(0, separator));
          writeStringLength(tmpWriter, token.substring(separator + 1));
        } else {
          writeStringLength(tmpWriter, token);
          writeStringLength(tmpWriter, "");
        }
      }
    }

    writer.writeLength(tmpWriter.pos());
    writer.writeBytes(tmpWriter.buf(), 0, tmpWriter.pos());
  }

  @Override
  public int encode(Writer writer, Context context) throws IOException {

    final byte[] authData;
    if ("mysql_clear_password".equals(authenticationPluginType)) {
      if (!context.hasClientCapability(SSL)) {
        throw new IllegalStateException("Cannot send password in clear if SSL is not enabled.");
      }
      authData =
          (password == null) ? new byte[0] : password.toString().getBytes(StandardCharsets.UTF_8);
    } else {
      authenticationPluginType = "mysql_native_password";
      authData = NativePasswordPlugin.encryptPassword(password, seed);
    }

    writer.writeInt((int) clientCapabilities);
    writer.writeInt(1024 * 1024 * 1024);
    writer.writeByte(exchangeCharset); // 1

    writer.writeBytes(new byte[19]); // 19
    writer.writeInt((int) (clientCapabilities >> 32)); // Maria extended flag

    writer.writeString(username != null ? username : System.getProperty("user.name"));
    writer.writeByte(0x00);

    if (context.hasServerCapability(PLUGIN_AUTH_LENENC_CLIENT_DATA)) {
      writer.writeLength(authData.length);
      writer.writeBytes(authData);
    } else if (context.hasServerCapability(SECURE_CONNECTION)) {
      writer.writeByte((byte) authData.length);
      writer.writeBytes(authData);
    } else {
      writer.writeBytes(authData);
      writer.writeByte(0x00);
    }

    if (context.hasClientCapability(CONNECT_WITH_DB)) {
      writer.writeString(database);
      writer.writeByte(0x00);
    }

    if (context.hasServerCapability(PLUGIN_AUTH)) {
      writer.writeString(authenticationPluginType);
      writer.writeByte(0x00);
    }

    if (context.hasServerCapability(CONNECT_ATTRS)) {
      writeConnectAttributes(writer, connectionAttributes, host);
    }
    writer.flush();
    return 1;
  }
}
