package ticdc

import (
	"context"
	"errors"

	"github.com/pingcap/log"
	"github.com/tidbcloud/dataflow-service/app/repo"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/pkgv2/db"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type tiCDCCustomStorageRepo struct {
	dbProvider db.Provider
}

// NewTiCDCCustomStorageRepo creates a new CDCCustomStorageRepo.
func NewTiCDCCustomStorageRepo(dbProvider db.Provider) repo.TiCDCCustomStorageRepo {
	return &tiCDCCustomStorageRepo{
		dbProvider: dbProvider,
	}
}

// LoadByTiCDCClusterID loads a CDCCustomStorage from the database.
func (r *tiCDCCustomStorageRepo) LoadByTiCDCClusterID(
	ctx context.Context,
	ticdcClusterID uint64,
) (*entity.TiCDCCustomStorage, bizerr.BizError) {
	rdb := r.dbProvider.ReadDB(ctx)
	record := &entity.TiCDCCustomStorage{}
	err := entity.NewTiCDCCustomStorageQuerySet(rdb).
		TiCDCClusterIDEq(entity.ID(ticdcClusterID)).
		One(record)
	if err != nil {
		return nil, bizerr.WrapGormError(err, "load ticdc cluster custom storage occur error")
	}
	return record, nil
}

// Save saves a CDCCustomStorage to the database.
func (r *tiCDCCustomStorageRepo) Save(
	ctx context.Context,
	record *entity.TiCDCCustomStorage,
) bizerr.BizError {
	wdb := r.dbProvider.WriteDB(ctx)

	oldRecord := &entity.TiCDCCustomStorage{}
	err := entity.NewTiCDCCustomStorageQuerySet(wdb).
		TiCDCClusterIDEq(record.TiCDCClusterID).
		One(oldRecord)
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		log.Error("load cdc custom storage from db failed", zap.Error(err))
		return bizerr.WrapGormError(err, "load cdc custom storage from db failed")
	}

	if err == nil {
		record.ID = oldRecord.ID
	}

	err = wdb.Save(record).Error
	if err != nil {
		log.Error("save cdc custom storage to db failed", zap.Error(err))
		return bizerr.WrapGormError(err, "save cdc custom storage to db failed")
	}
	return nil
}
