package com.avairebot.orion.database.grammar.mysql;

import com.avairebot.orion.contracts.database.grammar.SelectGrammar;
import com.avairebot.orion.database.query.*;

import java.util.List;

public class Select extends SelectGrammar {
    @Override
    public String format(QueryBuilder builder) {
        buildColumns(builder);

        buildJoins(builder);

        buildWhereClause(builder);

        return finalize(builder);
    }

    private void buildColumns(QueryBuilder builder) {
        if (builder.getColumns().size() == 1) {
            String column = builder.getColumns().get(0);

            if (column.equals("*")) {
                query += "*";
            } else if (column.startsWith("RAW:")) {
                query += column.substring(4);
            }
        } else {
            builder.getColumns().stream().forEach((column) -> {
                query += formatField(column) + ", ";
            });

            removeLast(2);
        }

        query += String.format(" FROM %s ", formatField(builder.getTable()));
    }

    private void buildJoins(QueryBuilder builder) {
        List<JoinClause> joins = builder.getJoins();

        for (JoinClause join : joins) {
            if (join.clauses.isEmpty()) {
                continue;
            }

            addPart(String.format(" %s JOIN %s ON ", join.type.toUpperCase(), formatField(join.table)));

            int orderLength = 0;

            for (Clause clause : join.clauses) {
                String string = String.format(" %s %s %s",
                        formatField(clause.getOne()), clause.getIdentifier(), formatField((String) clause.getTwo())
                );

                if (clause.getOrder() == null) {
                    clause.setOrder(OperatorType.AND);
                }

                String operator = clause.getOrder().getOperator();

                orderLength = operator.length() + 2;
                addPart(String.format(string + " %s ", operator));
            }

            if (orderLength > 0) {
                removeLast(orderLength);
            }
        }
    }

    @Override
    protected String finalize(QueryBuilder builder) {
        if (!builder.getOrder().isEmpty()) {
            addPart(" ORDER BY ");

            for (QueryOrder order : builder.getOrder()) {
                if (order.getField() == null) {
                    continue;
                }

                if (order.isRawSQL()) {
                    addPart(" %s , ", order.getField());

                    continue;
                }

                if (order.getType() != null) {
                    addPart(" %s %s, ", formatField(order.getField()), order.getType().toUpperCase());
                }
            }

            removeLast(2);
        }

        if (builder.getTake() <= 0) {
            return query.trim() + ";";
        }

        if (builder.getTake() > 0) {
            addPart(String.format(" LIMIT %d", builder.getTake()));

            // The skip clause is placed inside the limit statement because LIMIT is 
            // required for the OFFSET to be regonized by the SQL server, placing
            // it outside will throw a Syntex Exception due to the missing limit.
            if (builder.getSkip() > 0) {
                addPart(String.format(" OFFSET %d", builder.getSkip()));
            }
        }

        addPart(";");

        return query;
    }
}

@@ -522,118 +522,202 @@
 s().
-size() == 1) %7B%0A            String column = builder.getColumns().get(0);%0A%0A            if (column.equals(%22*%22)) %7B
+isEmpty() %7C%7C builder.getColumns().size() == 1 && builder.getColumns().get(0).equals(%22*%22)) %7B%0A            query += String.format(%22* FROM %25s %22, formatField(builder.getTable()));%0A            return;
 %0A   
@@ -717,32 +717,35 @@
 rn;%0A        
+%7D%0A%0A
         
 query += %22*%22
@@ -736,23 +736,60 @@
     
-query += %22*%22;%0A 
+builder.getColumns().stream().forEach((column) -%3E %7B%0A
     
@@ -795,22 +795,16 @@
         
-%7D else
  if (col
@@ -853,16 +853,38 @@
 query +=
+ String.format(%22%25s, %22,
  column.
@@ -895,16 +895,17 @@
 tring(4)
+)
 ;%0A      
@@ -914,26 +914,19 @@
     
-%7D%0A
     
-    %7D else %7B
+return;
 %0A   
@@ -938,61 +938,10 @@
     
-builder.getColumns().stream().forEach((column) -%3E %7B%0A 
+%7D%0A
     
@@ -940,35 +940,32 @@
   %7D%0A            
-   
 query += formatF
@@ -997,21 +997,13 @@
     
-    
 %7D);%0A%0A
-    
     
@@ -1016,34 +1016,24 @@
 moveLast(2);
-%0A        %7D
 %0A%0A        qu
@@ -3103,17 +3103,16 @@
 LIMIT is
- 
 %0A       

Add support for single select colums in MySQl select grammar