/*
 * 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.openjpa.lib.jdbc;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.openjpa.lib.util.J2DoPrivHelper;

/*
 * Lots of this could be abstracted out into a word-wrapping class.
 */

/**
 * Converts single-line SQL strings into nicely-formatted
 * multi-line, indented statements.
 * Example: from PERSON t0, COMPANY t1 WHERE t0.ID = 10 AND \
 * t0.COMPANY_ID = t1.ID AND t1.NAME = 'OpenJPA'</code> becomes
 * <code>SELECT * FROM PERSON t0, COMPANY t1
 * WHERE t0.ID = 10 AND t0.COMPANY_ID = t1.ID AND t1.NAME = 'OpenJPA'\
 * </code> and
 * <code>INSERT INTO PERSON VALUES('Patrick', 'Linskey', 'OpenJPA', \
 * '202 595 2064 x1111')</code> becomes
 * <code>INSERT INTO PERSON VALUES('Patrick', 'Linskey', 'OpenJPA', '202
 * 595 2064 x1111')</code> etc.
 *
 * @author Patrick Linskey
 */
public class SQLFormatter {

    private boolean multiLine = false;
    private boolean doubleSpace = true;
    private String newline = J2DoPrivHelper.getLineSeparator();
    private int lineLength = 72;
    private String wrapIndent = "        ";
    private String clauseIndent = "    ";

    private static final String[] selectSeparators = new String[]{
        "FROM ", "WHERE ", "ORDER BY ", // ### is this order correct?
        "GROUP BY ", "HAVING ", };

    private static final String[] insertSeparators = new String[]{
        "VALUES ", };

    private static final String[] updateSeparators = new String[]{
        "SET ", "WHERE ", };

    private static final String[] deleteSeparators = new String[]{
        "WHERE ", };

    private static final String[] createTableSeparators = new String[]{
        "( ", };

    private static final String[] createIndexSeparators = new String[]{
        "ON ", "( ", };

    public void setNewline(String val) {
        newline = val;
    }

    public String getNewline() {
        return newline;
    }

    public void setLineLength(int val) {
        lineLength = val;
    }

    public int getLineLength() {
        return lineLength;
    }

    public void setWrapIndent(String val) {
        wrapIndent = val;
    }

    public String getWrapIndent() {
        return wrapIndent;
    }

    public void setClauseIndent(String val) {
        clauseIndent = val;
    }

    public String getClauseIndent() {
        return clauseIndent;
    }

    /**
     * If true, then try to parse multi-line SQL statements.
     */
    public void setMultiLine(boolean multiLine) {
        this.multiLine = multiLine;
    }

    /**
     * If true, then try to parse multi-line SQL statements.
     */
    public boolean getMultiLine() {
        return this.multiLine;
    }

    /**
     * If true, then output two lines after multi-line statements.
     */
    public void setDoubleSpace(boolean doubleSpace) {
        this.doubleSpace = doubleSpace;
    }

    /**
     * If true, then output two lines after multi-line statements.
     */
    public boolean getDoubleSpace() {
        return this.doubleSpace;
    }

    public Object prettyPrint(Object sqlObject) {
        if (!multiLine) {
            return prettyPrintLine(sqlObject);
        } else {
            StringBuilder sql = new StringBuilder(sqlObject.toString());
            StringBuilder buf = new StringBuilder(sql.length());

            while (sql.length() > 0) {
                String line = null;

                int index = Math.max(sql.toString().indexOf(";\n"),
                    sql.toString().indexOf(";\r"));
                if (index == -1)
                    line = sql.toString();
                else
                    line = sql.substring(0, index + 2);

                // remove the current line from the sql buffer
                sql.delete(0, line.length());

                buf.append(prettyPrintLine(line));
                for (int i = 0; i < 1 + (getDoubleSpace() ? 1 : 0); i++)
                    buf.append(J2DoPrivHelper.getLineSeparator());
            }

            return buf.toString();
        }
    }

    private Object prettyPrintLine(Object sqlObject) {
        String sql = sqlObject.toString().trim();
        String lowerCaseSql = sql.toLowerCase();

        String[] separators;
        if (lowerCaseSql.startsWith("select"))
            separators = selectSeparators;
        else if (lowerCaseSql.startsWith("insert"))
            separators = insertSeparators;
        else if (lowerCaseSql.startsWith("update"))
            separators = updateSeparators;
        else if (lowerCaseSql.startsWith("delete"))
            separators = deleteSeparators;
        else if (lowerCaseSql.startsWith("create table"))
            separators = createTableSeparators;
        else if (lowerCaseSql.startsWith("create index"))
            separators = createIndexSeparators;
        else
            separators = new String[0];

        int start = 0;
        int end = -1;
        StringBuilder clause;
        List<StringBuilder> clauses = new ArrayList<>();
        clauses.add(new StringBuilder());
        for (String separator : separators) {
            end = lowerCaseSql.indexOf(" " + separator.toLowerCase(),
                    start);
            if (end == -1)
                break;

            clause = clauses.get(clauses.size() - 1);
            clause.append(sql.substring(start, end));

            clause = new StringBuilder();
            clauses.add(clause);
            clause.append(clauseIndent);
            clause.append(separator);

            start = end + 1 + separator.length();
        }

        clause = clauses.get(clauses.size() - 1);
        clause.append(sql.substring(start));

        StringBuilder pp = new StringBuilder(sql.length());
        for (Iterator<StringBuilder> iter = clauses.iterator(); iter.hasNext();){
            pp.append(wrapLine(iter.next().toString()));
            if (iter.hasNext())
                pp.append(newline);
        }

        return pp.toString();
    }

    private String wrapLine(String line) {
        StringBuilder lines = new StringBuilder(line.length());

        // ensure that any leading whitespace is preserved.
        for (int i = 0; i < line.length() &&
            (line.charAt(i) == ' ' || line.charAt(i) == '\t'); i++) {
            lines.append(line.charAt(i));
        }

        StringTokenizer tok = new StringTokenizer(line);
        int length = 0;
        String elem;
        while (tok.hasMoreTokens()) {
            elem = tok.nextToken();
            length += elem.length();

            // if we would have exceeded the max, write out a newline
            // before writing the elem.
            if (length >= lineLength) {
                lines.append(newline);
                lines.append(wrapIndent);
                lines.append(elem);
                lines.append(' ');
                length = wrapIndent.length() + elem.length() + 1;
                continue;
            }

            // if the current length is greater than the max, then the
            // last word alone was too long, so just write out a
            // newline and move on.
            if (elem.length() >= lineLength) {
                lines.append(elem);
                if (tok.hasMoreTokens())
                    lines.append(newline);
                lines.append(wrapIndent);
                length = wrapIndent.length();
                continue;
            }

            lines.append(elem);
            lines.append(' ');
            length++;
        }

        return lines.toString();
    }

    public static void main(String [] args) {
        SQLFormatter formatter = new SQLFormatter();
        for (String arg : args) {
            // START - ALLOW PRINT STATEMENTS
            System.out.println(formatter.prettyPrint(arg));
            // STOP - ALLOW PRINT STATEMENTS
        }
    }
}
