package cmd

import (
	"fmt"
	"io/ioutil"
	"os"
	"regexp"

	"github.com/hpcloud/tail"
	log "github.com/sirupsen/logrus"
	"gopkg.in/cheggaaa/pb.v1"
)

func init() {
	log.SetFormatter(&log.TextFormatter{DisableLevelTruncation: true, DisableTimestamp: true})
}

func cdWorkerDir() {
	err := os.Chdir("worker")
	if err != nil {
		log.Fatalf("failed to change the current working directory to worker directory, err: %v", err)
	}
}

func checkDataDirExist() {
	fi, err := os.Stat("data")
	if os.IsNotExist(err) {
		log.Fatalf("data directory not found, err: %v", err)
	}

	if !fi.IsDir() {
		log.Fatalln("data is not a directory")
	}
}

func checkInventoryExist() {
	if _, err := os.Stat(inventoryFilePath); os.IsNotExist(err) {
		log.Fatalf("Please run the `./tidb-enterprise.sh install` command first, err: %v", err)
	}
}

func createTaskLogfile() {
	if _, err := os.Stat(logPath); os.IsNotExist(err) {
		err := os.Mkdir(logPath, 0755)
		if err != nil {
			log.Fatalf("failed to create log directory, err: %v", err)
		}
	}

	taskLogfile, err := os.Create(taskLogPath)
	if err != nil {
		log.Fatalf("failed to create task.log file, err: %v", err)
	}
	defer taskLogfile.Close()

	failedTaskLogfile, err := os.Create(failedTaskLogPath)
	if err != nil {
		log.Fatalf("failed to create task_failed.log file, err: %v", err)
	}
	defer failedTaskLogfile.Close()
}

func storeDashboardInfo(dashboardIP string) {
	dashboardInfoFile, err := os.Create(dashboardInfoFilePath)
	if err != nil {
		log.Fatalf("failed to create dashboard info file, err: %v", err)
	}
	defer dashboardInfoFile.Close()

	fmt.Fprintf(dashboardInfoFile, "To access the Dashboard UI: http://%s:8080\n", dashboardIP)
	dashboardInfoFile.Sync()
}

func storeTiDBInfo(tidbIPs []string) {
	tidbInfoFile, err := os.Create(tidbInfoFilePath)
	if err != nil {
		log.Fatalf("failed to create tidb info file, err: %v", err)
	}
	defer tidbInfoFile.Close()

	for _, tidbIP := range tidbIPs {
		fmt.Fprintf(tidbInfoFile, "mysql -u root -h %s -P 4000\n", tidbIP)
	}

	tidbInfoFile.Sync()
}

func progressBar(count int) {
	bar := pb.New(count)
	bar.ShowCounters = true
	bar.ShowTimeLeft = false
	bar.SetWidth(96)
	bar.Start()

	t, _ := tail.TailFile(taskLogPath, tail.Config{Follow: true})
	re := regexp.MustCompile("^TASK")
	tasks := 0

	for line := range t.Lines {
		isTask := re.MatchString(line.Text)
		if isTask {
			tasks++
			bar.Increment()
		}

		if tasks == count {
			bar.Finish()
		}
	}
}

func printFailedLog() {
	message, err := ioutil.ReadFile(failedTaskLogPath)
	if err == nil && len(message) > 0 {
		log.Errorf("%s", message)
	}
}

func preTask() {
	cdWorkerDir()

	checkDataDirExist()

	checkInventoryExist()

	createTaskLogfile()
}

func postTask() {
	log.Infoln("Congratulation! All goes well.")
}
