package main

import (
	"database/sql"
	"fmt"

	"github.com/pingcap/errors"
	. "github.com/pingcap/tidb-test/large_txn"
)

// size = 1G | 3G | 10G
// action = DML | UPDATE | DELETE | INSERT INTO SELECT | LOAD DATA
// mode = optimistic | pessimistic | mix
// conflict = read | write
// chaos = schema change | kill pd | kill tidb | shuffle region | shuffle leader

const PKSize = 30000000

func main() {
	fmt.Println("load data test=====")
	loadDataTest()

	fmt.Println("insert into test====")
	insertIntoSelectTest()

	fmt.Println("update test======")
	updateTest()

	fmt.Println("large dml test====")
	largeDMLTest()

	fmt.Println("delete test======")
	deleteTest()
}

type prepareTask struct{}

func (prepareTask) CreateTable(db *sql.DB) error {
	sql1 := `create table if not exists sbtest1 (
id int(11) not null primary key,
k int(11) not null,
c char(120) not null default '',
pad char(255) not null default '')`
	_, err := db.Exec(sql1)
	if err != nil {
		return errors.WithStack(err)
	}

	sql2 := `create table if not exists sbtest2 (
id int(11) not null primary key,
k int(11) not null,
c char(120) not null default '',
pad char(255) not null default '',
index i_k(k))`
	_, err = db.Exec(sql2)
	if err != nil {
		return errors.WithStack(err)
	}
	return nil
}

func (prepareTask) InsertData(worker *Worker, db *sql.DB) error {
	return nil
}

func loadDataTest() {
	conf := Config{
		Conn:    DefaultConnConfig(),
		Prepare: PrepareConfig{Task: prepareTask{}},
		Run: RunConfig{
			Large: LargeTxnConfig{
				TxnMode: Pessimistic,
				Task:    LoadData("/tmp/data.txt"),
			},
			Small: SmallTxnConfig{
				WorkerCount: 32,
				TxnMode:     Optimistic,
				Task: SelectRandomPoints{
					Table: "sbtest1",
					Size:  PKSize,
				},
			},
		},
		Clean: DummyCleanTask{},
	}
	Run(&conf)
}

func insertIntoSelectTest() {
	conf := Config{
		Conn:    DefaultConnConfig(),
		Prepare: DummyPrepareConfig(),
		Run: RunConfig{
			Large: LargeTxnConfig{
				TxnMode: Optimistic,
				Task:    InsertIntoSelect{},
			},
			Small: SmallTxnConfig{
				WorkerCount: 32,
				TxnMode:     Pessimistic,
				Task: SelectSinglePoint{
					Table:      "sbtest2",
					PointRange: PKSize,
				},
			},
		},
		Clean: DummyCleanTask{},
	}
	Run(&conf)
}

func updateTest() {
	conf := Config{
		Conn:    DefaultConnConfig(),
		Prepare: DummyPrepareConfig(),
		Run: RunConfig{
			Large: LargeTxnConfig{
				TxnMode: Pessimistic,
				Task:    LargeUpdate{Table: "sbtest2"},
			},
			Small: SmallTxnConfig{
				WorkerCount: 32,
				TxnMode:     Optimistic,
				Task: SinglePointDoubleRead{
					Table: "sbtest2",
					Range: 512,
				},
			},
		},
		Clean: DummyCleanTask{},
	}
	Run(&conf)
}

func largeDMLTest() {
	conf := Config{
		Conn:    DefaultConnConfig(),
		Prepare: DummyPrepareConfig(),
		Run: RunConfig{
			Large: LargeTxnConfig{
				TxnMode: Optimistic,
				Task: LargeDML{
					PKRange: PKSize,
				},
			},
			Small: SmallTxnConfig{
				WorkerCount: 32,
				TxnMode:     Optimistic,
				Task: SelectRandomPoints{
					Table: "sbtest2",
					Size:  PKSize,
				},
			},
		},
		Clean: DummyCleanTask{},
	}
	Run(&conf)
}

func deleteTest() {
	conf := Config{
		Conn:    DefaultConnConfig(),
		Prepare: DummyPrepareConfig(),
		Run: RunConfig{
			Large: LargeTxnConfig{
				TxnMode: Optimistic,
				Task:    LargeDelete{},
			},
			Small: SmallTxnConfig{
				WorkerCount: 32,
				TxnMode:     Pessimistic,
				Task: SelectRandomPoints{
					Table: "sbtest1",
					Size:  PKSize,
				},
			},
		},
		Clean: DummyCleanTask{},
	}
	Run(&conf)
}
