package queries

import "fmt"

type SqliteQueries struct{}

func (q *SqliteQueries) SetTimeout(milliseconds int) string {
	return `PRAGMA noop`
}

// creates the versions table if it does not exist
func (q *SqliteQueries) CreateVersionsTable() string {
	return `CREATE TABLE IF NOT EXISTS iceman_versions (
		version int NOT NULL PRIMARY KEY
	)`
}

// gets the latest version added to the table
func (q *SqliteQueries) GetDataVersion() string {
	return `SELECT MAX(version) FROM iceman_versions`
}

// inserts a new version into the version table
func (q *SqliteQueries) InsertVersion() string {
	return `INSERT INTO iceman_versions (version) VALUES ($1)`
}

// creates the migration table if it does not exist
func (q *SqliteQueries) CreateMigrationsTable() string {
	return `CREATE TABLE IF NOT EXISTS iceman_migrations (
				id varchar NOT NULL PRIMARY KEY,
				name varchar NOT NULL,
				created_at timestamp NOT NULL,
				applied_at timestamp NOT NULL
            )`
}

// add entry to table after applying migration
func (q *SqliteQueries) InsertMigration() string {
	return "INSERT INTO iceman_migrations (id, name, created_at, applied_at) VALUES ($1, $2, $3, $4)"
}

// remove entry from table after rolling back migration
func (q *SqliteQueries) DeleteMigration() string {
	return "DELETE FROM iceman_migrations WHERE id = $1"
}

// creates bulk table if it does not exist
func (q *SqliteQueries) CreateBulkTable() string {
	return `CREATE TABLE IF NOT EXISTS iceman_bulk (
				id varchar NOT NULL PRIMARY KEY,
				name varchar NOT NULL,
				executed_at timestamp NOT NULL,
				complete boolean NOT NULL,
				next_row int NOT NULL
            )`
}

func (q *SqliteQueries) BulkTableV2() string {
	return `PRAGMA noop`
}

// create entry after executing new bulk operation
func (q *SqliteQueries) InsertBulk() string {
	return `INSERT INTO iceman_bulk (id, name, executed_at, complete, next_row) 
			VALUES ($1, $2, $3, $4, $5)
	`
}

func (q *SqliteQueries) UpdateBulk() string {
	return `UPDATE iceman_bulk SET executed_at = $1, complete = $2, next_row = $3 WHERE id = $4`
}

func (q *SqliteQueries) GetAllIds() string {
	return "SELECT id FROM iceman_migrations"
}

func (q *SqliteQueries) GetAllMigrations() string {
	return "SELECT * FROM iceman_migrations"
}

func (q *SqliteQueries) GetLastApplied() string {
	return `SELECT id FROM iceman_migrations
				WHERE applied_at = (SELECT MAX(applied_at) FROM iceman_migrations)
				ORDER BY created_at DESC LIMIT 1`
}

func (q *SqliteQueries) GetAllBulks() string {
	return `SELECT id, executed_at, complete, next_row FROM iceman_bulk`
}

func (q *SqliteQueries) GetSingleBulk() string {
	return `SELECT id, executed_at, complete, next_row FROM iceman_bulk WHERE id = $1`
}

func (q *SqliteQueries) GetSingleBulkByFilename() string {
	return `SELECT id, executed_at, complete, next_row FROM iceman_bulk WHERE name = $1`
}

func (q *SqliteQueries) FormatArray(elements []interface{}) []interface{} {
	return elements
}

func (q *SqliteQueries) SelectIdBetween() string {
	return "SELECT id FROM %v WHERE id >= $1 AND id < $2"
}

func (q *SqliteQueries) AndIdBetween() string {
	return "AND (%v.id >= $1 AND %v.id < $2)"
}

func (q *SqliteQueries) CreatePlaceholders(count int) string {

	comma := ""
	placeholders := ""

	// Not that this is 1-based
	for i := 1; i <= count; i++ {
		placeholders += fmt.Sprintf("%v$%v", comma, i)
		comma = ", "
	}
	return placeholders
}
