/*
 * Copyright 2026 Oleg Borodin <onborodin@gmail.com>
 *
 * This work is published and licensed under a Creative Commons
 * Attribution-NonCommercial-NoDerivatives 4.0 International License.
 *
 * Distribution of this work is permitted, but commercial use and
 * modifications are strictly prohibited.
 */
package test

import (
	"context"
	"fmt"
	"sync"
	"testing"
	"time"

	"mstore/app/server"
	"mstore/pkg/client"

	"github.com/stretchr/testify/require"
	yaml "go.yaml.in/yaml/v4"
)

func TestImageLife(t *testing.T) {
	var srvport int64 = 10250
	srvdir := t.TempDir()
	srvaddr := fmt.Sprintf("mstore:mstore@127.0.0.1:%d", srvport)

	srv, err := server.NewServer()
	require.NoError(t, err)
	{
		err = srv.Configure()
		require.NoError(t, err)

		useTmp := true
		if useTmp {
			srv.SetDatadir(srvdir)
			srv.SetLogdir(srvdir)
			srv.SetRundir(srvdir)
		}
		srv.SetPort(srvport)

		err = srv.Build()
		require.NoError(t, err)

		var svcWG sync.WaitGroup
		errPipe := make(chan error, 5)

		startFunc := func() {
			err := srv.Service().Run()
			errPipe <- err
			svcWG.Done()
		}

		stopFunc := func() {
			time.Sleep(5 * time.Second)
			srv.Service().Stop()
			svcWG.Wait()
			err = <-errPipe
			require.NoError(t, err)
		}
		defer stopFunc()

		svcWG.Add(1)
		go startFunc()
		time.Sleep(1 * time.Second)
	}
	{
		// ServiceHello
		fmt.Printf("=== ServiceHello ===\n")
		cli := client.NewClient()
		ctx := context.Background()
		helloRes, err := cli.ServiceHello(ctx, srvaddr+"/hello", 1*time.Second)
		require.NoError(t, err)
		require.True(t, helloRes)
	}
	{
		// PishImage
		fmt.Printf("=== PushImage ===\n")
		cli := client.NewClient()
		ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
		err := cli.PushImage(ctx, "test-oci.tar", srvaddr+"/foo/test:123")
		require.NoError(t, err)
	}
	{
		// ImageInfo
		fmt.Printf("=== ImageInfo ===\n")
		cli := client.NewClient()
		ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
		info, err := cli.ImageInfo(ctx, srvaddr+"/foo/test:123")
		require.NoError(t, err)
		infoYaml, err := yaml.Marshal(info)
		require.NoError(t, err)
		fmt.Printf("imageInfo:\n%s\n", string(infoYaml))
	}
	{
		// DeleteImage
		fmt.Printf("=== DeleteImage ===\n")
		cli := client.NewClient()
		ctx, _ := context.WithTimeout(context.Background(), 1*time.Second)
		err := cli.DeleteImage(ctx, srvaddr+"/foo/test:123")
		require.NoError(t, err)
	}
}
