package main

import (
	"flag"
	"fmt"
	"github.com/pingcap/schrodinger/pkg/test_client"
	"golang.org/x/net/context"
	"io/ioutil"
	"os"
	"os/exec"
	"os/signal"
	"syscall"
)

var (
	minBlobSize = flag.Int("min-blob-size", 64, "Smallest blob to store in a file. Blobs smaller than this "+
                "will be inlined with the key in the LSM tree.")
	valueSizeMult = flag.Int("value-size-mult", 33, "Size of value will be this number times rand_int(1,3) bytes")
)

func main() {
	flag.Parse()
	client.Info("[titandb_stress] start...")

	_, cancel := context.WithCancel(context.Background())

	sc := make(chan os.Signal, 1)
	signal.Notify(sc,
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGTERM,
		syscall.SIGQUIT)
	go func() {
		sig := <-sc
		client.Infof("[titandb_stress] Got signal [%s] to exist.", sig)
		cancel()
		os.Exit(0)
	}()


	client.Info("[titandb_stress] Running shell command: db_stress")

	cmdProps := fmt.Sprintf("--ops_per_thread=10000 --threads=40 --value_size_mult=%d " +
	        "--set_options_one_in=1000 --compact_range_one_in=1000 " +
	        "--acquire_snapshot_one_in=1 --ingest_external_file_one_in=1000 " +
	        "--compact_files_one_in=0 --checkpoint_one_in=0 " +
		"--backup_one_in=0 --nooverwritepercent=0 --delrangepercent=10 " + 
	        "--delpercent=15 --readpercent=15 --writepercent=30 --iterpercent=15 " +
	        "--prefixpercent=15 --max_background_compactions=20 --max_background_flushes=20 " +
	        "--enable_pipelined_write=true --min_blob_size=%d", *valueSizeMult, *minBlobSize)
	cmd := exec.Command("sh", "-c", fmt.Sprintf("/usr/local/titandb/bin/titandb_stress %s", cmdProps))
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		client.Fatalf("[titandb_stress] Get titandb_stress stdout error %v", client.ErrorStack(err))
	}
	if err := cmd.Start(); err != nil {
		client.Fatalf("[titandb_stress] Start titandb_stress error %v", client.ErrorStack(err))
	}

	b, err := ioutil.ReadAll(stdout)
	if err != nil {
		client.Fatalf("[titandb_stress] Read titandb_stress stdout out error %v", client.ErrorStack(err))
	} else {
		client.Infof("[titandb_stress] Read titandb_stress stdout %s", b)
	}

	if err := cmd.Wait(); err != nil {
		client.Fatalf("[titandb_stress] titandb_stress exit error %v", client.ErrorStack(err))
	}
	client.Infof("[titandb_stress] Finish titandb_stress")
}
