// Package repository add by blacknc <blacknc@163.com> at 2023/09/21 15:48:41
package repository

import (
	"context"
	"dataservices/commons/errs"
	"dataservices/commons/utils"
	"dataservices/internal/entity"
	"fmt"
	"time"
)

func CreateCommonTask(ctx context.Context, task *entity.CommonTask) error {
	task.CreatedAt = utils.Now()
	task.UpdatedAt = utils.Now()
	err := MustFromContext(ctx).Table(entity.TableCommonTasks).Create(task).Error
	if err != nil {
		return errs.WrapGORMError(err, "failed to create common task")
	}
	return nil
}

func UpdateCommonTask(ctx context.Context, task *entity.CommonTask) error {
	task.UpdatedAt = utils.Now()
	res := MustFromContext(ctx).Table(entity.TableCommonTasks).Updates(task)
	if err := res.Error; err != nil {
		return errs.WrapGORMError(err, "failed to create common task")
	} else if res.RowsAffected == 0 {
		return errs.NewInternalDB(fmt.Sprintf("update nothing for common task:%d", task.ID), nil)
	}
	return nil
}

func SelectCommonTasksByEvent(ctx context.Context, taskType string, eventID uint64, status []string) ([]*entity.CommonTask, error) {
	var tasks []*entity.CommonTask
	err := MustFromContext(ctx).Table(entity.TableCommonTasks).
		Where("task_type = ? AND event_id = ? AND status IN ?", taskType, eventID, status).
		Order("id DESC").
		Find(&tasks).Error
	if err != nil {
		return nil, errs.WrapGORMError(err, "failed to get sample dataapp task by id")
	}
	return tasks, nil
}

func GetSampleDataappTask(ctx context.Context, dataappID uint64) (*entity.CommonTask, error) {
	var task entity.CommonTask
	err := MustFromContext(ctx).Table(entity.TableCommonTasks).
		Where("task_type = ? AND event_id = ?", entity.CommonTaskTypeSampleData, dataappID).
		First(&task).Error
	if err != nil {
		return nil, errs.WrapGORMError(err, "failed to get sample dataapp task by id")
	}
	return &task, nil
}

func SelectCommonTaskForRun(ctx context.Context) ([]*entity.CommonTask, error) {
	var tasks []*entity.CommonTask
	now := time.Now().Unix()
	err := MustFromContext(ctx).Table(entity.TableCommonTasks).
		Where("status = ?", entity.CommonTaskStatusPending).
		Or("status = ? AND updated_at <= NOW() - INTERVAL 5 MINUTE", entity.CommonTaskStatusRunning).
		Or("status = ? AND next_retry <= ?", entity.CommonTaskStatusDormant, now).
		Find(&tasks).Error
	if err != nil {
		return nil, errs.WrapGORMError(err, "failed to select common task for run")
	}
	return tasks, nil
}

func SelectCommonTaskByID(ctx context.Context, taskID uint64) (*entity.CommonTask, error) {
	var task entity.CommonTask
	err := MustFromContext(ctx).Table(entity.TableCommonTasks).
		Where("id = ?", taskID).
		First(&task).Error
	if err != nil {
		return nil, errs.WrapGORMError(err, "failed to select common task by id")
	}
	return &task, nil
}
