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

__all__ = ['format_sql_commands', 'format_sql_file', 'format_sql_files']

# Cell
import re
import os
import tempfile
from glob import glob
from fastcore.script import call_parse, Param, store_true
from .core import *
from .utils import *
from .validation import *

# Cell
def format_sql_commands(s):
    "Format SQL commands in `s`"
    s = s.strip()  # strip file contents
    split_s = split_by_semicolon(s)  # split by query
    # validate semicolon
    validations_semicolon = [validate_semicolon(sp) for sp in split_s]
    val_summary_semicolon = sum([val["exit_code"] for val in validations_semicolon])
    # validate balanced parenthesis
    validations_balanced = [validate_balanced_parenthesis(sp) for sp in split_s]
    val_summary_balanced = sum([val["exit_code"] for val in validations_balanced])
    if sum([val_summary_semicolon, val_summary_balanced]) == 0:
        # format only SQL queries, let everything else unchanged
        formatted_split_s = [
            "\n\n\n" + format_sql(sp, add_semicolon=False).strip()
            if check_sql_query(sp) and not check_skip_marker(sp)
            else sp
            for sp in split_s
        ]
        # join by semicolon
        formatted_s = ";".join(formatted_split_s)
        # remove starting and ending newlines
        formatted_s = formatted_s.strip()
        # add newline at the end of file
        formatted_s = formatted_s + "\n"
        return formatted_s
    else:
        error_dict = {}
        if val_summary_semicolon > 0:
            file_lines = [
                tuple([line + sum([sd["total_lines"] for sd in validations_semicolon[0:i]]) for line in d["val_lines"]])
                for i, d in enumerate(validations_semicolon)
                if d["exit_code"] == 1
            ]
            error_dict["semicolon"] = {
                "error_code": 2,
                "lines": file_lines
            }
        if val_summary_balanced > 0:
            file_lines = [
                [line + sum([sd["total_lines"] for sd in validations_balanced[0:i]]) for line in d["val_lines"]]
                for i, d in enumerate(validations_balanced)
                if d["exit_code"] == 1
            ]
            error_dict["unbalanced"] = {
                "error_code": 3,
                "lines": file_lines
            }
        return error_dict

# Cell
def format_sql_file(f):
    """Format file `f` with SQL commands and overwrite the file.

    Return exit_code:
    * 0 = Everything already formatted
    * 1 = Formatting applied
    * 2 = Problem detected, formatting aborted
    """
    # open the file
    with open(f, "r") as file:
        sql_commands = file.read()
    # format SQL statements
    formatted_file = format_sql_commands(sql_commands)
    if isinstance(formatted_file, dict):
        print(f"Something went wrong in file: {f}")
        if "semicolon" in formatted_file.keys():
            print(
                (
                "Identified CREATE keyword more than twice within the same query " +
                f"at lines {formatted_file['semicolon']['lines']}\n"
                "You may have forgotten a semicolon (;) to delimit the queries"
                )
            )
        if "unbalanced" in formatted_file.keys():
            print(
                (
                "Identified unbalanced parenthesis " +
                f"at lines {formatted_file['unbalanced']['lines']}\n"
                "You should check your parenthesis"
                )
            )
        print(f"Aborting formatting for file {f}")
        exit_code = 2
    else:
        exit_code = 0 if sql_commands == formatted_file else 1
        # overwrite file
        with open(f, "w") as f:
            f.write(formatted_file)
    return exit_code

# Cell
@call_parse
def format_sql_files(
    files: Param(help='(Relative) path to SQL files. You can also use wildcard using ".*sql"', type=str, nargs="+"),
    recursive: Param(help="Should files also be searched in subfolders?", type=store_true)=False
):
    "Format SQL `files`"
    exit_codes = []
    # if wildcard "*" is input then use it
    if len(files) == 1 and re.search("\*", files[0]):
        if recursive:  # if recursive search
            files = glob(os.path.join("**", files[0]), recursive=True)
        else:
            files = glob(files[0])
    for file in files:
        exit_codes.append(format_sql_file(file))
    if sum(exit_codes) == 0:
        print("Nothing to format, everything is fine!")
    else:
        print("All specified files were formatted!")