# AUTOGENERATED! DO NOT EDIT! File to edit: nbs/03_validation.ipynb (unless otherwise specified).

__all__ = ['validate_semicolon', 'validate_balanced_parenthesis']

# Cell
from .utils import *

# Cell
def validate_semicolon(s):
    """Validate query `s` by looking for forgotten semicolon.
    The implication could be the keyword CREATE appearing twice"""
    positions = identify_create(s)
    if len(positions) > 1:
        validation = {
            "exit_code": 1,
            "val_lines": find_line_number(s, positions),
            "total_lines": count_lines(s)
        }
    else:
        validation = {
            "exit_code": 0,
            "total_lines": count_lines(s)
        }
    return validation

# Cell
def validate_balanced_parenthesis(s):
    """Validate query `s` by looking for
    unbalanced parenthesis

    exit_code:
    * 0 = balanced parenthesis
    * 1 = unbalanced parenthesis, too many (
    * 2 = unbalanced parenthesis, too many )
    """
    positions = []  # container for position of unbalanced parenthesis
    # counter for comments
    k = 0  # 0 = no comment range
    comment_open1 = False # comment indicator for /* */ comments
    comment_open2 = False  # comment indicator for -- comments
    quote_open1 = False  # quote '
    quote_open2 = False # quote "
    for i, c in enumerate(s):
        if c == "(" and k == 0:
            positions.append(i)
        elif c == ")" and k == 0:
            if len(positions) == 0:
                return {
                    "exit_code": 1,
                    "val_lines": find_line_number(s, [i]),
                    "total_lines": count_lines(s)
                }
            else:
                positions.pop()
        elif (
            s[i:i+2] == "/*" and
            not comment_open1 and
            not comment_open2 and
            not quote_open1 and
            not quote_open2
        ):  # if there is an opening comment /*
            k += 1
            comment_open1 = True
        elif (
            s[i:i+2] == "*/" and
            comment_open1 and
            not comment_open2 and
            not quote_open1 and
            not quote_open2
        ):  # if there is a closing comment */
            k -= 1
            comment_open1 = False
        elif (
            s[i:i+2] == "--" and
            not comment_open1 and
            not comment_open2 and
            not quote_open1 and
            not quote_open2
        ):  # if there is an opening comment --
            k += 1
            comment_open2 = True
        elif (
            (c == "\n" or s[i:i+3] == "[c]") and
            not comment_open1 and
            comment_open2 and
            not quote_open1 and
            not quote_open2
        ):  # if the -- comment ends
            k -= 1
            comment_open2 = False
        elif (
            c == "'" and
            not comment_open1 and
            not comment_open2 and
            not quote_open1 and
            not quote_open2
        ):  # if opening quote '
            k += 1
            quote_open1 = True
        elif (
            c == "'" and
            not comment_open1 and
            not comment_open2 and
            quote_open1 and
            not quote_open2
        ):  # if opening quote '
            k -= 1
            quote_open1 = False
        elif (
            c == '"' and
            not comment_open1 and
            not comment_open2 and
            not quote_open1 and
            quote_open2
        ):  # if opening quote '
            k += 1
            quote_open2 = True
        elif (
            c == '"' and
            not comment_open1 and
            not comment_open2 and
            not quote_open1 and
            quote_open2
        ):  # if opening quote '
            k -= 1
            quote_open2 = False
    if len(positions) == 0:
        return {
            "exit_code": 0,
            "total_lines": count_lines(s)
        }
    else:
        return {
            "exit_code": 1,
            "val_lines": find_line_number(s, positions),
            "total_lines": count_lines(s)
        }