package resolvers

// 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.64

import (
	"context"
	"sort"

	"github.com/bitmagnet-io/bitmagnet/internal/database/query"
	"github.com/bitmagnet-io/bitmagnet/internal/gql"
	"github.com/bitmagnet-io/bitmagnet/internal/gql/gqlmodel"
	"github.com/bitmagnet-io/bitmagnet/internal/gql/gqlmodel/gen"
	"github.com/bitmagnet-io/bitmagnet/internal/health"
	"github.com/bitmagnet-io/bitmagnet/internal/model"
	"github.com/bitmagnet-io/bitmagnet/internal/version"
)

// Version is the resolver for the version field.
func (r *queryResolver) Version(ctx context.Context) (string, error) {
	return version.GitTag, nil
}

// Workers is the resolver for the workers field.
func (r *queryResolver) Workers(ctx context.Context) (gen.WorkersQuery, error) {
	var workers []gen.Worker
	for _, w := range r.Resolver.Workers.Workers() {
		workers = append(workers, gen.Worker{
			Key:     w.Key(),
			Started: w.Started(),
		})
	}

	return gen.WorkersQuery{
		ListAll: gen.WorkersListAllQueryResult{
			Workers: workers,
		},
	}, nil
}

// Health is the resolver for the health field.
func (r *queryResolver) Health(ctx context.Context) (gen.HealthQuery, error) {
	transformHealthCheckStatus := func(s health.AvailabilityStatus) gen.HealthStatus {
		switch s {
		case health.StatusInactive:
			return gen.HealthStatusInactive
		case health.StatusDown:
			return gen.HealthStatusDown
		case health.StatusUp:
			return gen.HealthStatusUp
		default:
			return gen.HealthStatusUnknown
		}
	}
	check := r.Checker.Check(ctx)
	checks := make([]gen.HealthCheck, 0, len(check.Details))

	for k, v := range check.Details {
		var err *string

		if v.Error != nil {
			strErr := v.Error.Error()
			err = &strErr
		}

		checks = append(checks, gen.HealthCheck{
			Key:       k,
			Status:    transformHealthCheckStatus(v.Status),
			Timestamp: v.Timestamp,
			Error:     err,
		})
	}

	sort.Slice(checks, func(i, j int) bool {
		return checks[i].Key < checks[j].Key
	})

	result := gen.HealthQuery{
		Status: transformHealthCheckStatus(check.Status),
		Checks: checks,
	}

	return result, nil
}

// Queue is the resolver for the queue field.
func (r *queryResolver) Queue(ctx context.Context) (gqlmodel.QueueQuery, error) {
	return gqlmodel.QueueQuery{QueueMetricsClient: r.QueueMetricsClient}, nil
}

// Torrent is the resolver for the torrent field.
func (r *queryResolver) Torrent(ctx context.Context) (gqlmodel.TorrentQuery, error) {
	return gqlmodel.TorrentQuery{
		Dao:                  r.Dao,
		Search:               r.Search,
		TorrentMetricsClient: r.TorrentMetricsClient,
	}, nil
}

// TorrentContent is the resolver for the torrentContent field.
func (r *queryResolver) TorrentContent(ctx context.Context) (gqlmodel.TorrentContentQuery, error) {
	return gqlmodel.TorrentContentQuery{
		TorrentContentSearch: r.Search,
	}, nil
}

// Files is the resolver for the files field.
func (r *torrentQueryResolver) Files(ctx context.Context, obj *gqlmodel.TorrentQuery, input gqlmodel.TorrentFilesQueryInput) (query.GenericResult[model.TorrentFile], error) {
	return gqlmodel.TorrentQuery{
		Search: r.Search,
	}.Files(ctx, input)
}

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

// TorrentQuery returns gql.TorrentQueryResolver implementation.
func (r *Resolver) TorrentQuery() gql.TorrentQueryResolver { return &torrentQueryResolver{r} }

type queryResolver struct{ *Resolver }
type torrentQueryResolver struct{ *Resolver }
