// Contains numerous pre-written SQL queries
// to update migration and bulk tables
package queries

import (
	"fmt"
)

type MySQLQueries struct{}

// TODO - This is a hack - we need to put in a better dummy statement, or not run this statement
func (q *MySQLQueries) SetTimeout(milliseconds int) string {
	return fmt.Sprintf("SET @statement_timeout=%d", milliseconds)
}

// creates the versions table if it does not exist
func (q *MySQLQueries) 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 *MySQLQueries) GetDataVersion() string {
	return `SELECT MAX(version) FROM iceman_versions`
}

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

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

// add entry to table after applying migration
func (q *MySQLQueries) InsertMigration() string {
	return "INSERT INTO iceman_migrations (id, name, created_at, applied_at) VALUES (?, ?, ?, ?)"
}

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

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

func (q *MySQLQueries) BulkTableV2() string {
	return `ALTER TABLE iceman_bulk MODIFY next_row BIGINT NOT NULL`
}

// create entry after executing new bulk operation
func (q *MySQLQueries) InsertBulk() string {
	return `INSERT INTO iceman_bulk (id, name, executed_at, complete, next_row) 
			VALUES (?, ?, ?, ?, ?)
	`
}

// Update bulk run stats
func (q *MySQLQueries) UpdateBulk() string {
	return `UPDATE iceman_bulk SET executed_at = ?, complete = ?, next_row = ? WHERE id = ?`
}

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

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

func (q *MySQLQueries) 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 *MySQLQueries) GetAllBulks() string {
	return `SELECT id, executed_at, complete, next_row FROM iceman_bulk`
}

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

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

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

func (q *MySQLQueries) SelectIdBetween() string {
	return "SELECT id FROM %v WHERE id >= ? AND id < ?"
}

func (q *MySQLQueries) AndIdBetween() string {
	return "AND (%v.id >= ? AND %v.id < ?)"
}

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

	comma := ""
	placeholders := ""

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