/*
Copyright © 2024 Mark Bailey <gitea.com/cerbervs>
This file is part of a CLI application developed by Mark Bailey
*/
package cmd

import (
	"bytes"
	"fmt"
	"log"
	"os/exec"
	"regexp"
	"sort"
	"time"

	"github.com/spf13/cobra"
)

type kv struct {
	Key   string
	Value time.Time
}

var getVersionsCmd = &cobra.Command{
	Use:   "get-versions",
	Short: "Get the versions of a flatpak by package name as commit hashes.",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		versions := GetVersions(args[0])
		sortedVersions := sortByKeys(versions)

		for _, k := range sortedVersions {
			fmt.Println("Date: "+k.Value.Format(time.DateTime), "Version: "+k.Key)
		}
	},
}

func GetVersions(pkgName string) map[string]time.Time {
	cmd := exec.Command("flatpak", "remote-info", "--log", "flathub", pkgName)
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		log.Fatal(err)
	}
	output := out.String()

	commitRegex := regexp.MustCompile(`(?m)Commit: (.*)`)
	dateRegex := regexp.MustCompile(`(?m)Date: (.*)`)
	_ = dateRegex

	versions := make(map[string]time.Time)
	commitMatches := commitRegex.FindAllStringSubmatch(output, -1)
	dateMatches := dateRegex.FindAllStringSubmatch(output, -1)
	for i, match := range commitMatches {
		t, err := time.Parse("2006-01-02 15:04:05 -0700", dateMatches[i][1])
		if err != nil {
			continue
		}
		versions[match[1]] = t
	}

	return versions
}

func GetPreviousVersion(pkgName string) string {
	versions := GetVersions(pkgName)
	sortedVersions := sortByKeys(versions)
	var previousVersion string

	for i, k := range sortedVersions {
		if i == 1 {
			previousVersion = k.Key
		}
	}

	return previousVersion
}

func splitByNewline(s string) []string {
	strNormalized := regexp.
		MustCompile("\r\n").
		ReplaceAllString(s, "\n")
	return regexp.
		MustCompile("^s*\n").
		Split(strNormalized, -1)
}

func sortByKeys(m map[string]time.Time) []kv {
	var ss []kv
	for k, v := range m {
		ss = append(ss, kv{k, v})
	}
	sort.Slice(ss, func(i, j int) bool {
		return ss[i].Value.After(ss[j].Value)
	})

	return ss
}

func init() {
	rootCmd.AddCommand(getVersionsCmd)
}
