package storage

import (
	"context"
	"errors"
	"time"

	"git.unistack.org/unistack-org/pkgdash/internal/models"
	pb "git.unistack.org/unistack-org/pkgdash/proto"
	"github.com/jmoiron/sqlx"
)

func RegisterStorage(name string, fn func(*sqlx.DB) interface{}) {
	storages[name] = fn
}

var storages = map[string]func(*sqlx.DB) interface{}{}

type Storage interface {
	PackageModulesCreate(ctx context.Context, pkg *models.Package, modules []*models.Module) error
	PackagesUpdateLastCheck(ctx context.Context, packages []*models.Package) error
	PackageModules(ctx context.Context, req *pb.PackageModulesReq) ([]*models.Module, error)
	ModulesProcess(ctx context.Context, td time.Duration) ([]*models.Module, error)
	PackagesProcess(ctx context.Context, td time.Duration) ([]*models.Package, error)
	PackageCreate(ctx context.Context, req *pb.PackageCreateReq) (*models.Package, error)
	HandlerList(ctx context.Context, req *pb.HandlerListReq) ([]*models.Handler, error)
	PackageList(ctx context.Context, req *pb.PackageListReq) ([]*models.Package, error)
	PackageLookup(ctx context.Context, req *pb.PackageLookupReq) (*models.Package, error)
	PackageUpdate(ctx context.Context, req *pb.PackageUpdateReq) (*models.Package, error)
	PackageDelete(ctx context.Context, req *pb.PackageDeleteReq) error
	CommentCreate(ctx context.Context, req *pb.CommentCreateReq) (*models.Comment, error)
	CommentDelete(ctx context.Context, req *pb.CommentDeleteReq) error
	CommentList(ctx context.Context, req *pb.CommentListReq) ([]*models.Comment, error)
	ModuleList(ctx context.Context, req *pb.ModuleListReq) ([]*models.Module, error)
	ModuleCreate(ctx context.Context, modules []*models.Module) error
}

func NewStorage(name string, db *sqlx.DB) (Storage, error) {
	function, ok := storages[name]
	if !ok {
		return nil, errors.New("incorrect name store")
	}
	store := function(db)
	database, ok := store.(Storage)
	if !ok {
		return nil, errors.New("dont implements interface Storage")
	}
	return database, nil
}
