/*
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 */


package org.opensearch.jdbc.internal.util;


/**
 * Rudimentary SQL parser to help with very basic
 * driver side validations.
 */
public class SqlParser {

    public static int countParameterMarkers(String sql) {
        if (sql == null)
            return 0;

        int count = 0;

        for (int i=0; i < sql.length(); i++) {

            char ch = sql.charAt(i);

            switch (ch) {
                case '\'':
                case '\"':
                    i = locateQuoteEnd(sql, ch, i+1);
                    break;
                case '?':
                    count++;
                    break;
                case '-':
                case '/':
                    i = locateCommentEnd(sql, ch, i);
            }

        }
        return count;
    }

    private static int locateCommentEnd(String s, char commentStartChar, int commentStartIndex) {
        if (commentStartIndex + 1 > s.length())
            return commentStartIndex;

        int idx;

        if (commentStartChar == '-' && s.charAt(commentStartIndex + 1) == '-') {
            // single line comment
            idx = locateLineEnd(s, commentStartIndex + 2);

        } else if (commentStartChar == '/' && s.charAt(commentStartIndex + 1) == '*') {
            // multi line comment
            idx = s.indexOf("*/", commentStartIndex + 2);

        } else {
            // not on a comment
            return commentStartIndex;
        }
        
        if (idx == -1)
            throw new IllegalArgumentException("SQL text contains an unterminated comment.");
        else
            return idx;
    }

    private static int locateQuoteEnd(String s, char ch, int fromIndex) {
        int idx = s.indexOf(ch, fromIndex);
        if (idx == -1)
            throw new IllegalArgumentException("SQL text contains an unterminated string. " +
                    "This could possibly be due to mismatched quotes in the statement.");
        return idx;
    }


    private static int locateLineEnd(String s, int fromIndex) {
        int idx;

        for (idx=fromIndex; idx < s.length(); idx++) {
            char ch = s.charAt(idx);

            if (ch == '\r' || ch == '\n')
                break;
        }
        return idx;
    }
}