package utils

import (
	"fmt"
	"strings"

	"github.com/go-openapi/swag"
	"github.com/pingcap/errors"
)

const (
	ScheduleLength = 7
)

func ConvertBackupTimeByUTCOffset(backupTime string, utcOffset int32) (string, error) {
	if backupTime == "" {
		return "", errors.New("empty backupTime")
	}
	timeArr := strings.Split(backupTime, ":")
	if len(timeArr) != 2 {
		return "", fmt.Errorf("invalid backupTime format %s", backupTime)
	}

	hour, err := parseHour(timeArr[0])
	if err != nil {
		return "", err
	}
	minute, err := parseMinute(timeArr[1])
	if err != nil {
		return "", err
	}

	var utcHour int32
	if hour+utcOffset >= 24 {
		utcHour = (hour + utcOffset) - 24
	} else if hour+utcOffset < 0 {
		utcHour = (hour + utcOffset) + 24
	} else {
		utcHour = hour + utcOffset
	}
	return fmt.Sprintf("%02d:%02d", utcHour, minute), nil
}

func parseHour(h string) (int32, error) {
	h = strings.TrimPrefix(h, "0")
	hour, err := swag.ConvertInt32(h)
	if err != nil {
		return hour, fmt.Errorf("failed to convert hour[%s] to integer, err: %v", h, err)
	}
	if hour < 0 || hour > 23 {
		return hour, fmt.Errorf("invalid hour: %d", hour)
	}
	return hour, nil
}

func parseMinute(m string) (int32, error) {
	m = strings.TrimPrefix(m, "0")
	minute, err := swag.ConvertInt32(m)
	if err != nil {
		return minute, fmt.Errorf("failed to convert minute[%s] to integer, err: %v", m, err)
	}
	if minute < 0 || minute > 59 {
		return minute, fmt.Errorf("invalid minute: %s", m)
	}
	return minute, nil
}

func ParseCron(schedule string) (string, error) {
	timeFormat := strings.Split(schedule, " ")
	if len(timeFormat) != ScheduleLength {
		return "", fmt.Errorf("invalid schedule %s", schedule)
	}
	utcHour, err := parseHour(timeFormat[2])
	if err != nil {
		return "", err
	}
	minute, err := parseMinute(timeFormat[1])
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%02d:%02d", utcHour, minute), nil
}

func GetCron(backupTime string) (string, error) {
	timeFormat := strings.Split(backupTime, ":")
	_, err := parseHour(timeFormat[0])
	if err != nil {
		return "", err
	}
	_, err = parseMinute(timeFormat[1])
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("0 %s %s 1/1 * ? *", timeFormat[1], timeFormat[0]), nil
}
