package liquibase.sqlgenerator.core;

import liquibase.database.Database;
import liquibase.database.typeconversion.TypeConverterFactory;
import liquibase.exception.ValidationErrors;
import liquibase.sql.Sql;
import liquibase.sql.UnparsedSql;
import liquibase.sqlgenerator.SqlGenerator;
import liquibase.sqlgenerator.SqlGeneratorChain;
import liquibase.statement.core.InsertStatement;

import java.util.Date;

public class InsertGenerator extends AbstractSqlGenerator<InsertStatement> {

    public ValidationErrors validate(InsertStatement insertStatement, Database database, SqlGeneratorChain sqlGeneratorChain) {
        ValidationErrors validationErrors = new ValidationErrors();
        validationErrors.checkRequiredField("tableName", insertStatement.getTableName());
        validationErrors.checkRequiredField("columns", insertStatement.getColumnValues());

        if (insertStatement.getSchemaName() != null && !database.supportsSchemas()) {
           validationErrors.addError("Database does not support schemas");
       }

        return validationErrors;
    }

    public Sql[] generateSql(InsertStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
        StringBuffer sql = new StringBuffer("INSERT INTO " + database.escapeTableName(statement.getSchemaName(), statement.getTableName()) + " (");
        for (String column : statement.getColumnValues().keySet()) {
            sql.append(database.escapeColumnName(statement.getSchemaName(), statement.getTableName(), column)).append(", ");
        }
        sql.deleteCharAt(sql.lastIndexOf(" "));
        sql.deleteCharAt(sql.lastIndexOf(","));

        sql.append(") VALUES (");

        for (String column : statement.getColumnValues().keySet()) {
            Object newValue = statement.getColumnValues().get(column);
            if (newValue == null || newValue.toString().equals("") || newValue.toString().equalsIgnoreCase("NULL")) {
                sql.append("NULL");
            } else if (newValue instanceof String && database.shouldQuoteValue(((String) newValue))) {
                sql.append("'").append(database.escapeStringForDatabase((String) newValue)).append("'");
            } else if (newValue instanceof Date) {
                sql.append(database.getDateLiteral(((Date) newValue)));
            } else if (newValue instanceof Boolean) {
                if (((Boolean) newValue)) {
                    sql.append(TypeConverterFactory.getInstance().findTypeConverter(database).getBooleanType().getTrueBooleanValue());
                } else {
                    sql.append(TypeConverterFactory.getInstance().findTypeConverter(database).getBooleanType().getFalseBooleanValue());
                }
            } else {
                sql.append(newValue);
            }
            sql.append(", ");
        }

        sql.deleteCharAt(sql.lastIndexOf(" "));
        sql.deleteCharAt(sql.lastIndexOf(","));

        sql.append(")");

        return new Sql[] {
                new UnparsedSql(sql.toString())
        };
    }
}

@@ -1875,53 +1875,80 @@
 lue 
-== null %7C%7C new
+instanceof String && database.shouldQuote
 Value
-.to
+(((
 String
-().equals(%22%22) %7C%7C 
+) newValue)) && !
 newV
@@ -1987,16 +1987,17 @@
 (%22NULL%22)
+ 
 ) %7B%0D%0A   
@@ -2025,115 +2025,158 @@
 nd(%22
-NULL%22);%0D%0A            %7D else if (newValue instanceof String && database.shouldQuote
+'%22).append(database.escapeStringForDatabase((String) newValue)).append(%22'%22);%0D%0A            %7D else if (newValue == null %7C%7C new
 Value
-(((
+.to
 String
-) newValue)
+().equals(%22%22
 )) %7B
@@ -2209,81 +2209,12 @@
 nd(%22
-'%22).append(database.escapeStringForDatabase((String) newValue)).append(%22'
+NULL
 %22);%0D

String value "" is translated to null value in InsertGenerator that is incorrect.