package action

import (
	"context"

	"github.com/tidbcloud/fastflow/pkg/entity/run"
	"github.com/tidbcloud/fastflow/pkg/utils"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/adapter/clusterproxy"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	tidbgrouprepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/tidbgroup"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/service/auditlog"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

type fakeTidbGroupRepo struct {
	groups []*entity.TidbGroup
}

func (f *fakeTidbGroupRepo) Create(context.Context, *entity.TidbGroup) bizerr.BizError {
	panic("not implemented")
}
func (f *fakeTidbGroupRepo) Save(context.Context, *entity.TidbGroup) bizerr.BizError {
	panic("not implemented")
}
func (f *fakeTidbGroupRepo) Load(context.Context, uint64, uint64) (*entity.TidbGroup, bizerr.BizError) {
	panic("not implemented")
}
func (f *fakeTidbGroupRepo) Delete(context.Context, *entity.TidbGroup) bizerr.BizError {
	panic("not implemented")
}
func (f *fakeTidbGroupRepo) DeleteByClusterId(context.Context, uint64) bizerr.BizError {
	panic("not implemented")
}
func (f *fakeTidbGroupRepo) Query(context.Context, *tidbgrouprepo.Filter) ([]*entity.TidbGroup, bizerr.BizError) {
	return f.groups, nil
}

type fakeAuditLogService struct {
	getProxyFn              func(context.Context, *entity.Cluster, *entity.Region, *entity.TidbGroup) (clusterproxy.ClusterProxy, bizerr.BizError)
	updateSettingViaAgentFn func(context.Context, *entity.Cluster, *entity.Region, *entity.TidbGroup, *globalngv1.AuditLogSetting) bizerr.BizError
	createRuleViaAgentFn    func(context.Context, *entity.Cluster, *entity.Region, *entity.TidbGroup, *globalngv1.AuditLogFilterRule) bizerr.BizError
	deleteRuleViaAgentFn    func(context.Context, *entity.Cluster, *entity.Region, *entity.TidbGroup, string) bizerr.BizError
	updateRuleViaAgentFn    func(context.Context, *entity.Cluster, *entity.Region, *entity.TidbGroup, *globalngv1.AuditLogFilterRule) bizerr.BizError
}

func (f *fakeAuditLogService) GetAuditLogSetting(context.Context, uint64) (*globalngv1.AuditLogSetting, bizerr.BizError) {
	panic("not implemented")
}

func (f *fakeAuditLogService) UpdateAuditLogSetting(
	context.Context,
	*globalngv1.AuditLogSetting,
	bool,
) (*globalngv1.AuditLogSetting, bizerr.BizError) {
	panic("not implemented")
}

func (f *fakeAuditLogService) ListAuditLogFilterRules(
	context.Context,
	*globalngv1.ListAuditLogFilterRulesRequest,
) ([]*globalngv1.AuditLogFilterRule, bizerr.BizError) {
	panic("not implemented")
}

func (f *fakeAuditLogService) CreateAuditLogFilterRule(
	context.Context,
	*globalngv1.AuditLogFilterRule,
	bool,
) (*globalngv1.AuditLogFilterRule, bizerr.BizError) {
	panic("not implemented")
}
func (f *fakeAuditLogService) DeleteAuditLogFilterRule(context.Context, *globalngv1.DeleteAuditLogFilterRuleRequest) bizerr.BizError {
	panic("not implemented")
}

func (f *fakeAuditLogService) UpdateAuditLogFilterRule(
	context.Context,
	*globalngv1.AuditLogFilterRule,
	bool,
) (*globalngv1.AuditLogFilterRule, bizerr.BizError) {
	panic("not implemented")
}

func (f *fakeAuditLogService) UpdateAuditLogSettingViaAgent(
	ctx context.Context,
	cluster *entity.Cluster,
	region *entity.Region,
	tidbgroup *entity.TidbGroup,
	setting *globalngv1.AuditLogSetting,
) bizerr.BizError {
	if f.updateSettingViaAgentFn == nil {
		return nil
	}
	return f.updateSettingViaAgentFn(ctx, cluster, region, tidbgroup, setting)
}

func (f *fakeAuditLogService) CreateAuditLogFilterRuleViaAgent(
	ctx context.Context,
	cluster *entity.Cluster,
	region *entity.Region,
	tidbgroup *entity.TidbGroup,
	rule *globalngv1.AuditLogFilterRule,
) bizerr.BizError {
	if f.createRuleViaAgentFn == nil {
		return nil
	}
	return f.createRuleViaAgentFn(ctx, cluster, region, tidbgroup, rule)
}

func (f *fakeAuditLogService) DeleteAuditLogFilterRuleViaAgent(
	ctx context.Context,
	cluster *entity.Cluster,
	region *entity.Region,
	tidbgroup *entity.TidbGroup,
	userExpr string,
) bizerr.BizError {
	if f.deleteRuleViaAgentFn == nil {
		return nil
	}
	return f.deleteRuleViaAgentFn(ctx, cluster, region, tidbgroup, userExpr)
}

func (f *fakeAuditLogService) UpdateAuditLogFilterRuleViaAgent(
	ctx context.Context,
	cluster *entity.Cluster,
	region *entity.Region,
	tidbgroup *entity.TidbGroup,
	rule *globalngv1.AuditLogFilterRule,
) bizerr.BizError {
	if f.updateRuleViaAgentFn == nil {
		return nil
	}
	return f.updateRuleViaAgentFn(ctx, cluster, region, tidbgroup, rule)
}

func (f *fakeAuditLogService) GetPlatformAdminClusterProxy(
	ctx context.Context,
	cluster *entity.Cluster,
	region *entity.Region,
	tidbgroup *entity.TidbGroup,
) (clusterproxy.ClusterProxy, bizerr.BizError) {
	if f.getProxyFn == nil {
		return nil, bizerr.New(bizerr.ErrCodeUnknown, "test proxy function is not configured")
	}
	return f.getProxyFn(ctx, cluster, region, tidbgroup)
}

type fakeExecuteContext struct {
	ctx  context.Context
	vars map[string]string
}

func (f *fakeExecuteContext) Context() context.Context {
	if f.ctx == nil {
		return context.Background()
	}
	return f.ctx
}
func (f *fakeExecuteContext) WithValue(key, value any) {
	f.ctx = context.WithValue(f.Context(), key, value)
}
func (f *fakeExecuteContext) ShareData() run.ShareDataOperator { return nil }
func (f *fakeExecuteContext) Trace(string, ...run.TraceOp)     {}
func (f *fakeExecuteContext) Tracef(string, ...any)            {}
func (f *fakeExecuteContext) GetVar(varName string) (string, bool) {
	v, ok := f.vars[varName]
	return v, ok
}
func (f *fakeExecuteContext) IterateVars(iterateFunc utils.KeyValueIterateFunc) {
	for k, v := range f.vars {
		if !iterateFunc(k, v) {
			return
		}
	}
}

var _ auditlog.Service = (*fakeAuditLogService)(nil)
var _ tidbgrouprepo.Repo = (*fakeTidbGroupRepo)(nil)
var _ run.ExecuteContext = (*fakeExecuteContext)(nil)
