package syncengine

import (
	"regexp"
	"strconv"
	"strings"
)

type RsyncStats struct {
	SentBytes     int64
	ReceivedBytes int64
	TotalSize     int64
	Speedup       float64
	FilesSent     int
	FilesTotal    int
}

type ProgressLine struct {
	Phase    string
	Percent  float64
	Files    int
	Total    int
	SentBytes int64
	XferedBytes int64
}

var (
	progressRegex = regexp.MustCompile(`\s*([\d,]+)\s+([\d,]+)\s+([\d%]+)\s*`)
	sentRegex     = regexp.MustCompile(`sent\s+([\d,]+)\s+bytes`)
	recvRegex     = regexp.MustCompile(`received\s+([\d,]+)\s+bytes`)
	totalRegex    = regexp.MustCompile(`total size is\s+([\d,]+)`)
	filesRegex    = regexp.MustCompile(`Number of files: ([\d,]+)`)
)

func ParseProgressLine(line string) *ProgressLine {
	if strings.Contains(line, "files to consider") || strings.Contains(line, "files...") {
		return &ProgressLine{Phase: "scanning"}
	}
	if strings.Contains(line, "building file list") {
		return &ProgressLine{Phase: "listing"}
	}
	if strings.Contains(line, "sent") && strings.Contains(line, "bytes") {
		return &ProgressLine{Phase: "stats"}
	}
	return nil
}

func ParseStatsLine(line string) (int64, bool) {
	m := sentRegex.FindStringSubmatch(line)
	if len(m) >= 2 {
		n, _ := strconv.ParseInt(strings.ReplaceAll(m[1], ",", ""), 10, 64)
		return n, true
	}
	return 0, false
}

func ParseFinalStats(output string) *RsyncStats {
	stats := &RsyncStats{}
	lines := strings.Split(output, "\n")
	for _, line := range lines {
		line = strings.TrimSpace(line)
		if m := sentRegex.FindStringSubmatch(line); len(m) >= 2 {
			stats.SentBytes, _ = strconv.ParseInt(strings.ReplaceAll(m[1], ",", ""), 10, 64)
		}
		if m := recvRegex.FindStringSubmatch(line); len(m) >= 2 {
			stats.ReceivedBytes, _ = strconv.ParseInt(strings.ReplaceAll(m[1], ",", ""), 10, 64)
		}
		if m := totalRegex.FindStringSubmatch(line); len(m) >= 2 {
			stats.TotalSize, _ = strconv.ParseInt(strings.ReplaceAll(m[1], ",", ""), 10, 64)
		}
		if m := filesRegex.FindStringSubmatch(line); len(m) >= 2 {
			stats.FilesTotal, _ = strconv.Atoi(strings.ReplaceAll(m[1], ",", ""))
		}
	}
	return stats
}
