package service

import (
	"context"
	"github.com/ocdp/cluster-service/internal/domain/entity"
	"github.com/ocdp/cluster-service/internal/domain/repository"
	"github.com/ocdp/cluster-service/internal/pkg/authz"
)

// ArtifactService Artifact 浏览领域服务
type ArtifactService struct {
	registryRepo repository.RegistryRepository
	ociClient    repository.OCIClient
}

// NewArtifactService 创建 Artifact 服务
func NewArtifactService(
	registryRepo repository.RegistryRepository,
	ociClient repository.OCIClient,
) *ArtifactService {
	return &ArtifactService{
		registryRepo: registryRepo,
		ociClient:    ociClient,
	}
}

// GetRegistry 获取 Registry 信息
func (s *ArtifactService) GetRegistry(ctx context.Context, registryID string) (*entity.Registry, error) {
	return s.visibleRegistry(ctx, registryID)
}

// ListRepositories 列出 Registry 中的 repositories
func (s *ArtifactService) ListRepositories(ctx context.Context, registryID, artifactType string) ([]string, error) {
	registry, err := s.visibleRegistry(ctx, registryID)
	if err != nil {
		return nil, entity.ErrRegistryNotFound
	}

	return s.ociClient.ListRepositories(ctx, registry, artifactType)
}

// ListArtifacts 列出 repository 中的所有 artifacts
func (s *ArtifactService) ListArtifacts(ctx context.Context, registryID, repository, mediaTypeFilter string) ([]*entity.Artifact, error) {
	registry, err := s.visibleRegistry(ctx, registryID)
	if err != nil {
		return nil, entity.ErrRegistryNotFound
	}

	return s.ociClient.ListArtifacts(ctx, registry, repository, mediaTypeFilter)
}

// GetArtifact 获取 artifact 详情
func (s *ArtifactService) GetArtifact(ctx context.Context, registryID, repository, reference string) (*entity.Artifact, error) {
	registry, err := s.visibleRegistry(ctx, registryID)
	if err != nil {
		return nil, entity.ErrRegistryNotFound
	}

	return s.ociClient.GetArtifact(ctx, registry, repository, reference)
}

// GetValuesSchema 获取 Helm Chart 的 values schema
func (s *ArtifactService) GetValuesSchema(ctx context.Context, registryID, repository, reference string) (string, error) {
	registry, err := s.visibleRegistry(ctx, registryID)
	if err != nil {
		return "", entity.ErrRegistryNotFound
	}

	return s.ociClient.GetValuesSchema(ctx, registry, repository, reference)
}

// GetValuesYAML 获取 Helm Chart 的原始 values.yaml
func (s *ArtifactService) GetValuesYAML(ctx context.Context, registryID, repository, reference string) (string, error) {
	registry, err := s.visibleRegistry(ctx, registryID)
	if err != nil {
		return "", entity.ErrRegistryNotFound
	}

	return s.ociClient.GetValuesYAML(ctx, registry, repository, reference)
}

// PullArtifact 下载 artifact
func (s *ArtifactService) PullArtifact(ctx context.Context, registryID, repository, reference, destPath string) error {
	registry, err := s.visibleRegistry(ctx, registryID)
	if err != nil {
		return entity.ErrRegistryNotFound
	}

	return s.ociClient.PullArtifact(ctx, registry, repository, reference, destPath)
}

func (s *ArtifactService) visibleRegistry(ctx context.Context, registryID string) (*entity.Registry, error) {
	principal, err := authz.RequirePrincipal(ctx)
	if err != nil {
		return nil, entity.ErrUnauthorized
	}
	registry, err := s.registryRepo.GetByID(ctx, registryID)
	if err != nil {
		return nil, entity.ErrRegistryNotFound
	}
	if !authz.CanReadResource(principal, registry.WorkspaceID, registry.OwnerID, registry.Visibility) {
		return nil, entity.ErrRegistryNotFound
	}
	return registry, nil
}
