/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.calcite.avatica;

import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

/**
 * ConnectStringParser is a utility class that parses or creates a JDBC connect
 * string according to the
 * <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms722656(v=vs.85).aspx">
 * OLE DB Connection String Syntax</a>.
 *
 * <p>This code was adapted from Mondrian's mondrian.olap.Util class.
 * The primary differences between this and its Mondrian progenitor are:
 *
 * <ul>
 * <li>use of regular {@link Properties} for compatibility with the JDBC API
 * (replaces Mondrian's use of its own order-preserving and case-insensitive
 * PropertyList)</li>
 *
 * <li>ability to pass to {@link #parse} a pre-existing Properties object into
 * which properties are to be parsed, possibly overriding prior values</li>
 *
 * <li>use of {@link SQLException}s rather than unchecked
 * {@link RuntimeException}s</li>
 *
 * <li>static members for parsing and creating connect strings</li>
 *
 * </ul>
 *
 * <p>ConnectStringParser has a private constructor. Callers use the static
 * members:
 *
 * <dl>
 * <dt>{@link #parse(String)}
 * <dd>Parses the connect string into a new Properties object.
 *
 * <dt>{@link #parse(String, Properties)}
 * <dd>Parses the connect string into an existing Properties object.
 *
 * <dt>{@link #getParamString(Properties)}
 * <dd>Returns a param string, quoted and escaped as needed, to represent the
 * supplied name-value pairs.
 * </dl>
 */
public class ConnectStringParser {
  //~ Instance fields --------------------------------------------------------

  private final String s;
  private final int n;
  private int i;
  private final StringBuilder nameBuf = new StringBuilder();
  private final StringBuilder valueBuf = new StringBuilder();

  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a new connect string parser.
   *
   * @param s connect string to parse
   *
   * @see #parse(String)
   * @see #parse(String, Properties)
   */
  private ConnectStringParser(String s) {
    this.s = s;
    this.i = 0;
    this.n = s.length();
  }

  //~ Methods ----------------------------------------------------------------

  /**
   * Parses the connect string into a new Properties object.
   *
   * @param s connect string to parse
   *
   * @return properties object with parsed params
   *
   * @throws SQLException error parsing name-value pairs
   */
  public static Properties parse(String s)
      throws SQLException {
    return new ConnectStringParser(s).parseInternal(null);
  }

  /**
   * Parses the connect string into an existing Properties object.
   *
   * @param s connect string to parse
   * @param props optional properties object, may be <code>null</code>
   *
   * @return properties object with parsed params; if an input <code>
   * props</code> was supplied, any duplicate properties will have been
   * replaced by those from the connect string.
   *
   * @throws SQLException error parsing name-value pairs
   */
  public static Properties parse(String s, Properties props)
      throws SQLException {
    return new ConnectStringParser(s).parseInternal(props);
  }

  /**
   * Parses the connect string into a Properties object. Note that the string
   * can only be parsed once. Subsequent calls return empty/unchanged
   * Properties. The original <code>props</code> argument is not altered.
   *
   * @param props optional properties object, may be <code>null</code>
   *
   * @return properties object with parsed params; if an input <code>
   * props</code> was supplied, any duplicate properties will have been
   * replaced by those from the connect string.
   *
   * @throws SQLException error parsing name-value pairs
   */
  Properties parseInternal(final Properties props)
      throws SQLException {
    final Properties newProps;
    if (props == null) {
      newProps = new Properties();
    } else {
      newProps = (Properties) props.clone();
    }
    while (i < n) {
      parsePair(newProps);
    }
    return newProps;
  }

  /**
   * Reads "name=value;" or "name=value&lt;EOF&gt;".
   *
   * @throws SQLException error parsing value
   */
  void parsePair(Properties props)
      throws SQLException {
    String name = parseName();
    String value;
    if (i >= n) {
      value = "";
    } else if (s.charAt(i) == ';') {
      i++;
      value = "";
    } else {
      value = parseValue();
    }
    props.put(name, value);
  }

  /**
   * Reads "name=". Name can contain equals sign if equals sign is doubled.
   */
  String parseName() {
    nameBuf.setLength(0);
    while (true) {
      char c = s.charAt(i);
      switch (c) {
      case '=':
        i++;
        if ((i < n) && ((c = s.charAt(i)) == '=')) {
          // doubled equals sign; take one of them, and carry on
          i++;
          nameBuf.append(c);
          break;
        }
        String name = nameBuf.toString();
        name = name.trim();
        return name;
      case ' ':
        if (nameBuf.length() == 0) {
          // ignore preceding spaces
          i++;
          break;
        }
        // fall through
      default:
        nameBuf.append(c);
        i++;
        if (i >= n) {
          return nameBuf.toString().trim();
        }
      }
    }
  }

  /**
   * Reads "value;" or "value&lt;EOF&gt;"
   *
   * @throws SQLException if find an unterminated quoted value
   */
  String parseValue()
      throws SQLException {
    char c;

    // skip over leading white space
    while ((c = s.charAt(i)) == ' ') {
      i++;
      if (i >= n) {
        return "";
      }
    }
    if ((c == '"') || (c == '\'')) {
      String value = parseQuoted(c);

      // skip over trailing white space
      while (i < n && s.charAt(i) == ' ') {
        i++;
      }
      if (i >= n) {
        return value;
      } else if (s.charAt(i) == ';') {
        i++;
        return value;
      } else {
        throw new SQLException(
            "quoted value ended too soon, at position " + i
                + " in '" + s + "'");
      }
    } else {
      String value;
      int semi = s.indexOf(';', i);
      if (semi >= 0) {
        value = s.substring(i, semi);
        i = semi + 1;
      } else {
        value = s.substring(i);
        i = n;
      }
      return value.trim();
    }
  }

  /**
   * Reads a string quoted by a given character. Occurrences of the quoting
   * character must be doubled. For example, <code>parseQuoted('"')</code>
   * reads <code>"a ""new"" string"</code> and returns <code>a "new"
   * string</code>.
   *
   * @throws SQLException if find an unterminated quoted value
   */
  String parseQuoted(char q)
      throws SQLException {
    char c = s.charAt(i++);
    if (c != q) {
      throw new AssertionError("c != q: c=" + c + " q=" + q);
    }
    valueBuf.setLength(0);
    while (i < n) {
      c = s.charAt(i);
      if (c == q) {
        i++;
        if (i < n) {
          c = s.charAt(i);
          if (c == q) {
            valueBuf.append(c);
            i++;
            continue;
          }
        }
        return valueBuf.toString();
      } else {
        valueBuf.append(c);
        i++;
      }
    }
    throw new SQLException(
        "Connect string '" + s
            + "' contains unterminated quoted value '"
            + valueBuf.toString() + "'");
  }

  /**
   * Returns a param string, quoted and escaped as needed, to represent the
   * supplied name-value pairs.
   *
   * @param props name-value pairs
   *
   * @return param string, never <code>null</code>
   */
  public static String getParamString(Properties props) {
    if (props == null) {
      return "";
    }

    StringBuilder buf = new StringBuilder();
    for (Map.Entry<String, String> entry : toMap(props).entrySet()) {
      final String name = entry.getKey();
      final String value = entry.getValue();
      String quote = "";
      if (buf.length() > 0) {
        buf.append(';');
      }

      // write parameter name
      if (name.startsWith(" ") || name.endsWith(" ")) {
        quote = "'";
        buf.append(quote);
      }
      int len = name.length();
      for (int i = 0; i < len; ++i) {
        char c = name.charAt(i);
        if (c == '=') {
          buf.append('=');
        }
        buf.append(c);
      }

      buf.append(quote); // might be empty
      quote = "";

      buf.append('=');

      // write parameter value
      len = value.length();
      boolean hasSemi = value.indexOf(';') >= 0;
      boolean hasSQ = value.indexOf('\'') >= 0;
      boolean hasDQ = value.indexOf('"') >= 0;
      if (value.startsWith(" ") || value.endsWith(" ")) {
        quote = "'";
      } else if (hasSemi || hasSQ || hasDQ) {
        // try to choose the least painful quote
        if (value.startsWith("\"")) {
          quote = "'";
        } else if (value.startsWith("'")) {
          quote = "\"";
        } else {
          quote = hasSQ ? "\"" : "'";
        }
      }
      char q;
      if (quote.length() > 0) {
        buf.append(quote);
        q = quote.charAt(0);
      } else {
        q = '\0';
      }
      for (int i = 0; i < len; ++i) {
        char c = value.charAt(i);
        if (c == q) {
          buf.append(q);
        }
        buf.append(c);
      }
      buf.append(quote); // might be empty
    }

    return buf.toString();
  }

  /**
   * Converts a {@link Properties} object to a <code>{@link Map}&lt;String,
   * String&gt;</code>.
   *
   * <p>This is necessary because {@link Properties} is a dinosaur class. It
   * ought to extend <code>Map&lt;String,String&gt;</code>, but instead
   * extends <code>{@link java.util.Hashtable}&lt;Object,Object&gt;</code>.
   *
   * <p>Typical usage, to iterate over a {@link Properties}:
   *
   * <blockquote>
   * <code>
   * Properties properties;<br>
   * for (Map.Entry&lt;String, String&gt; entry =
   * Util.toMap(properties).entrySet()) {<br>
   *   println("key=" + entry.getKey() + ", value=" + entry.getValue());<br>
   * }
   * </code>
   * </blockquote>
   */
  public static Map<String, String> toMap(
      final Properties properties) {
    //noinspection unchecked
    return (Map) properties;
  }
}

// End ConnectStringParser.java
