package main

import (
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"os/exec"

	"kisekinopureya.com.tr/updater/internal/archive"
)

func sha256sum(path string) (string, error) {
	f, err := os.Open(path)
	if err != nil {
		return "", err
	}
	defer f.Close()

	h := sha256.New()
	if _, err := io.Copy(h, f); err != nil {
		return "", err
	}
	return hex.EncodeToString(h.Sum(nil)), nil
}

func main() {
	if len(os.Args) != 3 {
		fmt.Printf("Usage: %s <archive.tar.xz> <archive.tar.xz.sig>\n", os.Args[0])
		os.Exit(1)
	}

	archiveFile := os.Args[1]
	sig := os.Args[2]

	// Step 1: verify GPG signature
	cmd := exec.Command("/usr/bin/gpgv", "--keyring", "/etc/updates-public.gpg", sig, archiveFile)

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		fmt.Fprintf(os.Stderr, "GPG verification failed: %v\n", err)
		os.Exit(1)
	}
	fmt.Println("GPG signature verified.")

	// Step 2: open archiveFile
	f, err := os.Open(archiveFile)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	// Step 2: extract tar.xz using system tar
	cmdTar := exec.Command("tar", "-xJf", archiveFile)
	cmdTar.Stdout = os.Stdout
	cmdTar.Stderr = os.Stderr
	if err := cmdTar.Run(); err != nil {
		panic(err)
	}

	metaFile := "metadata.json"
	f, err = os.Open(metaFile)
	if err != nil {
		panic(err)
	}
	defer f.Close()

	var meta archive.Output
	if err := json.NewDecoder(f).Decode(&meta); err != nil {
		panic(err)
	}

	// Step 4: check sha256
	ok := true
	for _, file := range meta.Files {
		sum, err := sha256sum(file.Name)
		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to hash %s: %v\n", file.Name, err)
			ok = false
			continue
		}
		if sum != file.Sha256 {
			fmt.Fprintf(os.Stderr, "Checksum mismatch for %s!\nExpected: %s\nGot:      %s\n",
				file.Name, file.Sha256, sum)
			ok = false
		} else {
			fmt.Printf("%s checksum OK\n", file.Name)
		}
	}

	if !ok {
		os.Exit(1)
	}

	fmt.Println("All files verified successfully.")
}
