package com.getbase.android.db.fluentsqlite;

import static com.google.common.base.Preconditions.checkNotNull;

import com.getbase.android.db.provider.Utils;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;

import java.util.Collections;
import java.util.List;

public class Insert implements InsertTableSelector, InsertFormSelector, InsertValuesBuilder {
  String mTable;
  ContentValues mValues = new ContentValues();
  List<String> mQueryFormColumns = Lists.newArrayList();

  private Insert() {
  }

  public static InsertTableSelector insert() {
    return new Insert();
  }

  public long perform(SQLiteDatabase db) {
    return db.insert(mTable, null, mValues);
  }

  public static class InsertWithSelect {
    private final String mTable;
    private final RawQuery mQuery;
    private final List<String> mQueryFormColumns;

    InsertWithSelect(String table, RawQuery query, List<String> queryFormColumns) {
      mTable = table;
      mQuery = query;
      mQueryFormColumns = queryFormColumns;
    }

    public long perform(SQLiteDatabase db) {
      StringBuilder builder = new StringBuilder();
      builder.append("INSERT INTO ").append(mTable).append(" ");
      if (!mQueryFormColumns.isEmpty()) {
        builder
            .append("(")
            .append(Joiner.on(", ").join(mQueryFormColumns))
            .append(") ");
      }
      builder.append(mQuery.mRawQuery);

      SQLiteStatement statement = db.compileStatement(builder.toString());
      try {
        int argIndex = 1;
        for (String arg : mQuery.mRawQueryArgs) {
          Utils.bindContentValueArg(statement, argIndex++, arg);
        }

        return statement.executeInsert();
      } finally {
        statement.close();
      }
    }
  }

  public static class DefaultValuesInsert {
    final String mTable;
    final String mNullColumnHack;

    private DefaultValuesInsert(String table, String nullColumnHack) {
      mTable = table;
      mNullColumnHack = nullColumnHack;
    }

    public void perform(SQLiteDatabase db) {
      db.insert(mTable, mNullColumnHack, null);
    }
  }

  @Override
  public InsertFormSelector into(String table) {
    mTable = checkNotNull(table);
    return this;
  }

  @Override
  public DefaultValuesInsert defaultValues(String nullColumnHack) {
    return new DefaultValuesInsert(mTable, checkNotNull(nullColumnHack));
  }

  @Override
  public InsertSubqueryForm columns(String... columns) {
    Preconditions.checkArgument(columns != null, "Column list cannot be null");
    Collections.addAll(mQueryFormColumns, columns);

    return this;
  }

  @Override
  public InsertWithSelect resultOf(Query query) {
    checkNotNull(query);

    return new InsertWithSelect(mTable, query.toRawQuery(), mQueryFormColumns);
  }

  @Override
  public Insert values(ContentValues values) {
    mValues.putAll(values);
    return this;
  }

  @Override
  public Insert value(String column, Object value) {
    Utils.addToContentValues(column, value, mValues);
    return this;
  }
}

@@ -504,41 +504,216 @@
 sert
-TableSelector,
+ValuesBuilder %7B%0A  final String mTable;%0A  final ContentValues mValues;%0A%0A  private Insert(String table, ContentValues values) %7B%0A    mTable = table;%0A    mValues = values;%0A  %7D%0A%0A  public static
  Insert
-Form
+Table
 Selector
 , In
@@ -712,251 +712,1282 @@
 ctor
-, InsertValuesBuilder %7B%0A  String mTable;%0A  ContentValues mValues = new ContentValues();%0A  List%3CString%3E mQueryFormColumns = Lists.newArrayList();%0A%0A  private Insert() %7B%0A
+ insert() %7B%0A    return new InsertBuilder();%0A  %7D%0A%0A  static class InsertBuilder implements InsertTableSelector, InsertFormSelector %7B%0A    String mTable;%0A    List%3CString%3E mQueryFormColumns = Lists.newArrayList();%0A%0A    @Override%0A    public InsertFormSelector into(String table) %7B%0A      mTable = checkNotNull(table);%0A      return this;%0A    %7D%0A%0A    @Override%0A    public DefaultValuesInsert defaultValues(String nullColumnHack) %7B%0A      return new DefaultValuesInsert(mTable, checkNotNull(nullColumnHack));%0A    %7D%0A%0A    @Override%0A    public InsertSubqueryForm columns(String... columns) %7B%0A      Preconditions.checkArgument(columns != null, %22Column list cannot be null%22);%0A      Collections.addAll(mQueryFormColumns, columns);%0A%0A      return this;%0A    %7D%0A%0A    @Override%0A    public InsertWithSelect resultOf(Query query) %7B%0A      checkNotNull(query);%0A%0A      return new InsertWithSelect(mTable, query.toRawQuery(), mQueryFormColumns);%0A 
   
+ 
 %7D%0A%0A  
-public static
+  @Override%0A    public Insert values(ContentValues values) %7B%0A      return new
  Insert
+(m
 Table
-Selector insert() %7B%0A    return new Insert();
+, new ContentValues(values));%0A    %7D%0A%0A    @Override%0A    public Insert value(String column, Object value) %7B%0A      ContentValues values = new ContentValues();%0A      Utils.addToContentValues(column, value, values);%0A%0A      return new Insert(mTable, values);%0A    %7D
 %0A  %7D
@@ -3498,681 +3498,8 @@
  %7D%0A%0A
-  @Override%0A  public InsertFormSelector into(String table) %7B%0A    mTable = checkNotNull(table);%0A    return this;%0A  %7D%0A%0A  @Override%0A  public DefaultValuesInsert defaultValues(String nullColumnHack) %7B%0A    return new DefaultValuesInsert(mTable, checkNotNull(nullColumnHack));%0A  %7D%0A%0A  @Override%0A  public InsertSubqueryForm columns(String... columns) %7B%0A    Preconditions.checkArgument(columns != null, %22Column list cannot be null%22);%0A    Collections.addAll(mQueryFormColumns, columns);%0A%0A    return this;%0A  %7D%0A%0A  @Override%0A  public InsertWithSelect resultOf(Query query) %7B%0A    checkNotNull(query);%0A%0A    return new InsertWithSelect(mTable, query.toRawQuery(), mQueryFormColumns);%0A  %7D%0A%0A
   @O

Fix botched fluent API for sqlite inserts