package main

import (
	"crypto/sha256"
	"fmt"
	"strconv"
	"strings"
)

// versi menyimpan komponen semver: MAJOR.MINOR.PATCH.
type versi struct {
	mayor int
	minor int
	patch int
}

// urai mengubah string semver menjadi struct versi.
func urai(s string) (versi, error) {
	bagian := strings.SplitN(s, ".", 3)
	if len(bagian) != 3 {
		return versi{}, fmt.Errorf("format salah: %q", s)
	}
	var angka [3]int
	for i, b := range bagian {
		n, err := strconv.Atoi(b)
		if err != nil {
			return versi{}, fmt.Errorf("komponen %q bukan angka", b)
		}
		angka[i] = n
	}
	return versi{angka[0], angka[1], angka[2]}, nil
}

// bandingkan mengembalikan -1, 0, atau 1 seperti strings.Compare.
func bandingkan(a, b versi) int {
	if a.mayor != b.mayor {
		if a.mayor < b.mayor {
			return -1
		}
		return 1
	}
	if a.minor != b.minor {
		if a.minor < b.minor {
			return -1
		}
		return 1
	}
	if a.patch != b.patch {
		if a.patch < b.patch {
			return -1
		}
		return 1
	}
	return 0
}

// artefak adalah satu berkas rilis dengan isi representatifnya.
type artefak struct {
	nama string
	isi  string
}

func main() {
	// Jebakan klasik: perbandingan string menganggap 1.10.0 lebih tua dari 1.9.0.
	fmt.Println(`perbandingan string "1.10.0" < "1.9.0":`, "1.10.0" < "1.9.0")

	pasangan := [][2]string{
		{"1.2.3", "1.2.3"},
		{"1.10.0", "1.9.0"},
		{"2.0.0", "1.99.9"},
	}
	for _, p := range pasangan {
		a, errA := urai(p[0])
		b, errB := urai(p[1])
		if errA != nil || errB != nil {
			fmt.Println("gagal mengurai pasangan", p[0], p[1])
			continue
		}
		tanda := "="
		switch bandingkan(a, b) {
		case -1:
			tanda = "<"
		case 1:
			tanda = ">"
		}
		fmt.Printf("perbandingan semver %s %s %s\n", p[0], tanda, p[1])
	}

	// Checksum tiap artefak rilis — isi sama menghasilkan checksum sama.
	kumpulan := []artefak{
		{"sapa-v1.2.3-linux-amd64", "binary linux/amd64 untuk sapa v1.2.3"},
		{"sapa-v1.2.3-linux-arm64", "binary linux/arm64 untuk sapa v1.2.3"},
		{"sapa-v1.2.3-darwin-arm64", "binary darwin/arm64 untuk sapa v1.2.3"},
	}
	fmt.Println("SHA256SUMS:")
	for _, a := range kumpulan {
		sum := sha256.Sum256([]byte(a.isi))
		fmt.Printf("%x  %s\n", sum, a.nama)
	}
}
