package large

import (
	"context"
	"database/sql"
	"fmt"
	"math/rand"

	_ "github.com/go-sql-driver/mysql"
	"github.com/pingcap/errors"
)

type SelectRandomPoints struct {
	Table string
	Size  int
}

func (s SelectRandomPoints) SmallTxn(worker *Worker, conn *sql.Conn) error {
	rows, err := conn.QueryContext(context.Background(), fmt.Sprintf("select id, k, c, pad from %s where id in (?, ?, ?)", s.Table), rand.Intn(s.Size), rand.Intn(s.Size), rand.Intn(s.Size))
	if err != nil {
		return errors.WithStack(err)
	}
	defer rows.Close()
	return nil
}

type UpdateRandomPoints struct {
}

func (_ UpdateRandomPoints) SmallTxn(worker *Worker, conn *sql.Conn) error {
	rows, err := conn.QueryContext(context.Background(), "update sbtest1 set k = k + 1 where id in (?, ?, ?)", rand.Intn(100000), rand.Intn(100000), rand.Intn(100000))
	if err != nil {
		return errors.WithStack(err)
	}
	defer rows.Close()
	return nil
}

type SelectRandomRanges struct {
}

func (_ SelectRandomRanges) SmallTxn(worker *Worker, conn *sql.Conn) error {
	return nil
}

type SelectSinglePoint struct {
	Table      string
	PointRange int
}

func (s SelectSinglePoint) SmallTxn(worker *Worker, conn *sql.Conn) error {
	rows, err := conn.QueryContext(context.Background(), fmt.Sprintf("select * from %s where id = ?", s.Table), rand.Intn(s.PointRange))
	if err != nil {
		return errors.WithStack(err)
	}
	defer rows.Close()
	return nil
}

func SelectSinglePointPK(table string, pointRange int) SelectSinglePoint {
	return SelectSinglePoint{
		Table:      table,
		PointRange: pointRange,
	}
}

type SinglePointDoubleRead struct {
	Table string
	Range int
}

func (s SinglePointDoubleRead) SmallTxn(worker *Worker, conn *sql.Conn) error {
	rows, err := conn.QueryContext(context.Background(), fmt.Sprintf("select id from %s where k = ? limit 1", s.Table), rand.Intn(s.Range))
	if err != nil {
		return errors.WithStack(err)
	}
	defer rows.Close()
	return nil
}

func SinglePointDoubleReadF(table string, valueRange int) SinglePointDoubleRead {
	return SinglePointDoubleRead{
		Table: table,
		Range: valueRange,
	}
}
