package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"path/filepath"

	"unprism.ru/KRBL/agate"
	"unprism.ru/KRBL/agate/stores"
)

func main() {
	// Create a temporary directory for our example
	workDir, err := os.MkdirTemp("", "agate-example-*")
	if err != nil {
		log.Fatalf("Failed to create work directory: %v", err)
	}
	defer os.RemoveAll(workDir) // Clean up when done

	// Create directories for metadata and blobs
	metadataDir := filepath.Join(workDir, "metadata")
	blobsDir := filepath.Join(workDir, "blobs")
	if err := os.MkdirAll(metadataDir, 0755); err != nil {
		log.Fatalf("Failed to create metadata directory: %v", err)
	}
	if err := os.MkdirAll(blobsDir, 0755); err != nil {
		log.Fatalf("Failed to create blobs directory: %v", err)
	}

	// Initialize the default stores
	metadataStore, blobStore, err := stores.InitDefaultStores(workDir)
	if err != nil {
		log.Fatalf("Failed to initialize stores: %v", err)
	}
	defer metadataStore.Close() // Clean up when done

	// Create a directory with some data to snapshot
	dataDir := filepath.Join(workDir, "data")
	if err := os.MkdirAll(dataDir, 0755); err != nil {
		log.Fatalf("Failed to create data directory: %v", err)
	}

	// Create a sample file
	sampleFile := filepath.Join(dataDir, "sample.txt")
	if err := os.WriteFile(sampleFile, []byte("Hello, Agate!"), 0644); err != nil {
		log.Fatalf("Failed to create sample file: %v", err)
	}

	// Define open and close functions
	openFunc := func(dir string) error {
		fmt.Printf("Opening resources in directory: %s\n", dir)
		return nil
	}

	closeFunc := func() error {
		fmt.Println("Closing resources...")
		return nil
	}

	// Initialize Agate
	agateOptions := agate.AgateOptions{
		WorkDir:       dataDir,
		OpenFunc:      openFunc,
		CloseFunc:     closeFunc,
		MetadataStore: metadataStore,
		BlobStore:     blobStore,
	}

	ag, err := agate.New(agateOptions)
	if err != nil {
		log.Fatalf("Failed to initialize Agate: %v", err)
	}
	defer ag.Close()

	// Create a snapshot
	ctx := context.Background()
	snapshotID, err := ag.SaveSnapshot(ctx, "My First Snapshot", "")
	if err != nil {
		log.Fatalf("Failed to create snapshot: %v", err)
	}
	fmt.Printf("Created snapshot with ID: %s\n", snapshotID)

	// List snapshots
	snapshots, err := ag.ListSnapshots(ctx)
	if err != nil {
		log.Fatalf("Failed to list snapshots: %v", err)
	}
	fmt.Printf("Found %d snapshots:\n", len(snapshots))
	for _, s := range snapshots {
		fmt.Printf("  - %s: %s (created at %s)\n", s.ID, s.Name, s.CreationTime.Format("2006-01-02 15:04:05"))
	}

	// Modify the file
	if err := os.WriteFile(sampleFile, []byte("Hello, Agate! (modified)"), 0644); err != nil {
		log.Fatalf("Failed to modify sample file: %v", err)
	}

	// Create another snapshot with the first one as parent
	snapshotID2, err := ag.SaveSnapshot(ctx, "My Second Snapshot", snapshotID)
	if err != nil {
		log.Fatalf("Failed to create second snapshot: %v", err)
	}
	fmt.Printf("Created second snapshot with ID: %s\n", snapshotID2)

	// Restore the first snapshot
	if err := ag.RestoreSnapshot(ctx, snapshotID); err != nil {
		log.Fatalf("Failed to restore snapshot: %v", err)
	}
	fmt.Println("Restored first snapshot")

	// Read the file content to verify it was restored
	content, err := os.ReadFile(sampleFile)
	if err != nil {
		log.Fatalf("Failed to read sample file: %v", err)
	}
	fmt.Printf("File content after restore: %s\n", content)

	fmt.Println("Example completed successfully!")
}
