package clients

import (
	"context"
	"fmt"

	"git.linuxforward.com/byop/byop-engine/models"
	"github.com/sirupsen/logrus"
)

// RegistryClient defines the interface for interacting with a Docker registry.
type RegistryClient interface {
	// PushImage pushes an image. fullImageURI includes the tag.
	// registryURL is the base URL of the registry (e.g., "docker.io", "myregistry.com") used for auth.
	PushImage(ctx context.Context, job models.BuildJob, fullImageURI string, registryURL string, username string, password string) error
	// CheckImageExists checks if an image exists in the registry
	CheckImageExists(ctx context.Context, fullImageURI string, registryURL string, username string, password string) (bool, error)
	// Authenticate() error // Future method
}

// SimpleRegistryClient is a basic implementation of RegistryClient that uses BuildKitClient for pushing.
type SimpleRegistryClient struct {
	entry          *logrus.Entry
	buildkitClient BuildMachineClient // Client to perform the actual build and push operations
}

// NewSimpleRegistryClient creates a new SimpleRegistryClient.
// It requires a BuildKitClient to delegate the push operation.
func NewSimpleRegistryClient(bkc BuildMachineClient) *SimpleRegistryClient {
	if bkc == nil {
		// Or handle this more gracefully, perhaps by returning an error
		panic("BuildKitClient cannot be nil for SimpleRegistryClient")
	}
	return &SimpleRegistryClient{
		entry:          logrus.WithField("component", "SimpleRegistryClient"),
		buildkitClient: bkc,
	}
}

// PushImage delegates the image push operation to the configured BuildKitClient.
func (src *SimpleRegistryClient) PushImage(ctx context.Context, job models.BuildJob, fullImageURI string, registryURL string, username string, password string) error {
	src.entry.Infof("Job %d: SimpleRegistryClient delegating push for %s to BuildKitClient", job.ID, fullImageURI)

	// Delegate to BuildKitClient's PushImage method
	// Note: The BuildKitClient.PushImage method itself handles the BuildKit session and solve options for pushing.
	err := src.buildkitClient.PushImage(ctx, job, fullImageURI, registryURL, username, password)
	if err != nil {
		return fmt.Errorf("job %d: BuildKitClient failed to push image %s: %w", job.ID, fullImageURI, err)
	}

	src.entry.Infof("Job %d: Image %s successfully pushed by BuildKitClient via SimpleRegistryClient.", job.ID, fullImageURI)
	return nil
}

// CheckImageExists checks if an image exists in the registry by delegating to BuildKitClient
func (src *SimpleRegistryClient) CheckImageExists(ctx context.Context, fullImageURI string, registryURL string, username string, password string) (bool, error) {
	src.entry.Infof("SimpleRegistryClient checking if image exists: %s", fullImageURI)

	// Delegate to BuildKitClient's CheckImageExists method
	exists, err := src.buildkitClient.CheckImageExists(ctx, fullImageURI, registryURL, username, password)
	if err != nil {
		return false, fmt.Errorf("BuildKitClient failed to check image existence %s: %w", fullImageURI, err)
	}

	src.entry.Infof("Image %s existence check result: %t", fullImageURI, exists)
	return exists, nil
}
