package search

// This file will be automatically regenerated based on the schema, any resolver implementations
// will be copied through when generating and any unknown code will be moved to the end.
// Code generated by github.com/99designs/gqlgen version v0.17.35

import (
	"context"

	"github.com/vektah/gqlparser/v2/gqlerror"
	zerr "zotregistry.io/zot/errors"
	"zotregistry.io/zot/pkg/common"
	"zotregistry.io/zot/pkg/extensions/search/gql_generated"
)

// CVEListForImage is the resolver for the CVEListForImage field.
func (r *queryResolver) CVEListForImage(ctx context.Context, image string, requestedPage *gql_generated.PageInput, searchedCve *string) (*gql_generated.CVEResultForImage, error) {
	if r.cveInfo == nil {
		return &gql_generated.CVEResultForImage{}, zerr.ErrCVESearchDisabled
	}

	if searchedCve == nil {
		return getCVEListForImage(ctx, image, r.cveInfo, requestedPage, "", r.log)
	}

	return getCVEListForImage(ctx, image, r.cveInfo, requestedPage, *searchedCve, r.log)
}

// ImageListForCve is the resolver for the ImageListForCVE field.
func (r *queryResolver) ImageListForCve(ctx context.Context, id string, filter *gql_generated.Filter, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
	if r.cveInfo == nil {
		return &gql_generated.PaginatedImagesResult{}, zerr.ErrCVESearchDisabled
	}

	filter = cleanFilter(filter)

	return getImageListForCVE(ctx, id, r.cveInfo, filter, requestedPage, r.metaDB, r.log)
}

// ImageListWithCVEFixed is the resolver for the ImageListWithCVEFixed field.
func (r *queryResolver) ImageListWithCVEFixed(ctx context.Context, id string, image string, filter *gql_generated.Filter, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
	if r.cveInfo == nil {
		return &gql_generated.PaginatedImagesResult{}, zerr.ErrCVESearchDisabled
	}

	filter = cleanFilter(filter)

	return getImageListWithCVEFixed(ctx, id, image, r.cveInfo, filter, requestedPage, r.metaDB, r.log)
}

// ImageListForDigest is the resolver for the ImageListForDigest field.
func (r *queryResolver) ImageListForDigest(ctx context.Context, id string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
	r.log.Info().Msg("extracting repositories")

	imgResultForDigest, err := getImageListForDigest(ctx, id, r.metaDB, r.cveInfo, requestedPage)

	return imgResultForDigest, err
}

// RepoListWithNewestImage is the resolver for the RepoListWithNewestImage field.
func (r *queryResolver) RepoListWithNewestImage(ctx context.Context, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedReposResult, error) {
	r.log.Info().Msg("extension api: finding image list")

	paginatedReposResult, err := repoListWithNewestImage(ctx, r.cveInfo, r.log, requestedPage, r.metaDB)
	if err != nil {
		r.log.Error().Err(err).Msg("unable to retrieve repo list")

		return paginatedReposResult, err
	}

	return paginatedReposResult, nil
}

// ImageList is the resolver for the ImageList field.
func (r *queryResolver) ImageList(ctx context.Context, repo string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
	r.log.Info().Msg("extension api: getting a list of all images")

	imageList, err := getImageList(ctx, repo, r.metaDB, r.cveInfo, requestedPage, r.log)
	if err != nil {
		r.log.Error().Err(err).Str("repository", repo).Msg("unable to retrieve image list for repo")

		return imageList, err
	}

	return imageList, nil
}

// ExpandedRepoInfo is the resolver for the ExpandedRepoInfo field.
func (r *queryResolver) ExpandedRepoInfo(ctx context.Context, repo string) (*gql_generated.RepoInfo, error) {
	repoInfo, err := expandedRepoInfo(ctx, repo, r.metaDB, r.cveInfo, r.log)

	return repoInfo, err
}

// GlobalSearch is the resolver for the GlobalSearch field.
func (r *queryResolver) GlobalSearch(ctx context.Context, query string, filter *gql_generated.Filter, requestedPage *gql_generated.PageInput) (*gql_generated.GlobalSearchResult, error) {
	if err := validateGlobalSearchInput(query, filter, requestedPage); err != nil {
		return &gql_generated.GlobalSearchResult{}, err
	}

	query = cleanQuery(query)
	filter = cleanFilter(filter)

	paginatedReposResult, images, layers, err := globalSearch(ctx, query, r.metaDB, filter, requestedPage, r.cveInfo, r.log)

	return &gql_generated.GlobalSearchResult{
		Page:   paginatedReposResult.Page,
		Images: images,
		Repos:  paginatedReposResult.Results,
		Layers: layers,
	}, err
}

// DependencyListForImage is the resolver for the DependencyListForImage field.
func (r *queryResolver) DerivedImageList(ctx context.Context, image string, digest *string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
	derivedList, err := derivedImageList(ctx, image, digest, r.metaDB, requestedPage, r.cveInfo, r.log)

	return derivedList, err
}

// BaseImageList is the resolver for the BaseImageList field.
func (r *queryResolver) BaseImageList(ctx context.Context, image string, digest *string, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedImagesResult, error) {
	imageList, err := baseImageList(ctx, image, digest, r.metaDB, requestedPage, r.cveInfo, r.log)

	return imageList, err
}

// Image is the resolver for the Image field.
func (r *queryResolver) Image(ctx context.Context, image string) (*gql_generated.ImageSummary, error) {
	repo, tag := common.GetImageDirAndTag(image)

	if tag == "" {
		return &gql_generated.ImageSummary{}, gqlerror.Errorf("no reference provided")
	}

	return getImageSummary(ctx, repo, tag, nil, r.metaDB, r.cveInfo, r.log)
}

// Referrers is the resolver for the Referrers field.
func (r *queryResolver) Referrers(ctx context.Context, repo string, digest string, typeArg []string) ([]*gql_generated.Referrer, error) {
	referrers, err := getReferrers(r.metaDB, repo, digest, typeArg, r.log)
	if err != nil {
		r.log.Error().Err(err).Msg("unable to get referrers from default store")

		return []*gql_generated.Referrer{}, err
	}

	return referrers, nil
}

// StarredRepos is the resolver for the StarredRepos field.
func (r *queryResolver) StarredRepos(ctx context.Context, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedReposResult, error) {
	return getStarredRepos(ctx, r.cveInfo, r.log, requestedPage, r.metaDB)
}

// BookmarkedRepos is the resolver for the BookmarkedRepos field.
func (r *queryResolver) BookmarkedRepos(ctx context.Context, requestedPage *gql_generated.PageInput) (*gql_generated.PaginatedReposResult, error) {
	return getBookmarkedRepos(ctx, r.cveInfo, r.log, requestedPage, r.metaDB)
}

// Query returns gql_generated.QueryResolver implementation.
func (r *Resolver) Query() gql_generated.QueryResolver { return &queryResolver{r} }

type queryResolver struct{ *Resolver }
