// 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;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.mariadb.jdbc.export.HaMode;

/** Host entry */
public class HostAddress {

  /** host address */
  public final String host;

  /** port */
  public int port;

  /** primary node */
  public Boolean primary;

  /**
   * Constructor.
   *
   * @param host host
   * @param port port
   * @param primary is primary
   */
  private HostAddress(String host, int port, Boolean primary) {
    this.host = host;
    this.port = port;
    this.primary = primary;
  }

  /**
   * Create a Host without knowledge of primary/replica goal
   *
   * @param host host (DNS/IP)
   * @param port port
   * @return host
   */
  public static HostAddress from(String host, int port) {
    return new HostAddress(host, port, null);
  }

  /**
   * Create a Host
   *
   * @param host host (DNS/IP)
   * @param port port
   * @param primary is primary
   * @return host
   */
  public static HostAddress from(String host, int port, boolean primary) {
    return new HostAddress(host, port, primary);
  }

  /**
   * parse - parse server addresses from the URL fragment.
   *
   * @param spec list of endpoints in one of the forms 1 - host1,....,hostN:port (missing port
   *     default to MariaDB default 3306 2 - host:port,...,host:port
   * @param haMode High availability mode
   * @throws SQLException for wrong spec
   * @return parsed endpoints
   */
  public static List<HostAddress> parse(String spec, HaMode haMode) throws SQLException {
    if ("".equals(spec)) {
      return new ArrayList<>(0);
    }
    String[] tokens = spec.trim().split(",");
    int size = tokens.length;
    List<HostAddress> arr = new ArrayList<>(size);

    for (int i = 0; i < tokens.length; i++) {
      String token = tokens[i];
      if (token.startsWith("address=")) {
        arr.add(parseParameterHostAddress(token, haMode, i == 0));
      } else {
        arr.add(parseSimpleHostAddress(token, haMode, i == 0));
      }
    }

    return arr;
  }

  private static HostAddress parseSimpleHostAddress(String str, HaMode haMode, boolean first)
      throws SQLException {
    String host;
    int port = 3306;

    if (str.charAt(0) == '[') {
      /* IPv6 addresses in URLs are enclosed in square brackets */
      int ind = str.indexOf(']');
      host = str.substring(1, ind);
      if (ind != (str.length() - 1) && str.charAt(ind + 1) == ':') {
        port = getPort(str.substring(ind + 2));
      }
    } else if (str.contains(":")) {
      /* Parse host:port */
      String[] hostPort = str.split(":");
      host = hostPort[0];
      port = getPort(hostPort[1]);
    } else {
      /* Just host name is given */
      host = str;
    }

    boolean primary = haMode != HaMode.REPLICATION || first;

    return new HostAddress(host, port, primary);
  }

  private static int getPort(String portString) throws SQLException {
    try {
      return Integer.parseInt(portString);
    } catch (NumberFormatException nfe) {
      throw new SQLException("Incorrect port value : " + portString);
    }
  }

  private static HostAddress parseParameterHostAddress(String str, HaMode haMode, boolean first)
      throws SQLException {
    String host = null;
    int port = 3306;
    Boolean primary = null;

    String[] array = str.replace(" ", "").split("(?=\\()|(?<=\\))");
    for (int i = 1; i < array.length; i++) {
      String[] token = array[i].replace("(", "").replace(")", "").trim().split("=");
      if (token.length != 2) {
        throw new IllegalArgumentException(
            "Invalid connection URL, expected key=value pairs, found " + array[i]);
      }
      String key = token[0].toLowerCase();
      String value = token[1].toLowerCase();

      switch (key) {
        case "host":
          host = value.replace("[", "").replace("]", "");
          break;
        case "port":
          port = getPort(value);
          break;
        case "type":
          if ("master".equalsIgnoreCase(value) || "primary".equalsIgnoreCase(value)) {
            primary = true;
          } else if ("slave".equalsIgnoreCase(value) || "replica".equalsIgnoreCase(value)) {
            primary = false;
          } else {
            throw new SQLException(
                String.format("Wrong type value %s (possible value primary/replica)", array[i]));
          }
          break;
      }
    }

    if (primary == null) {
      if (haMode == HaMode.REPLICATION) {
        primary = first;
      } else {
        primary = true;
      }
    }

    return new HostAddress(host, port, primary);
  }

  @Override
  public String toString() {
    return String.format(
        "address=(host=%s)(port=%s)%s",
        host, port, ((primary != null) ? ("(type=" + (primary ? "primary)" : "replica)")) : ""));
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    HostAddress that = (HostAddress) o;
    return port == that.port
        && Objects.equals(host, that.host)
        && Objects.equals(primary, that.primary);
  }

  @Override
  public int hashCode() {
    return Objects.hash(host, port, primary);
  }
}
